sql server 学习教程

SQL Server 系统数据库

在我们安装 SQL Server 的时候,会自动创建下面的四个数据库。

master

master 数据库记录了所有的 SQL Server 数据库系统的系统级信息,如用户帐户,配置设置,并在所有其他数据库信息。

model

model 数据库是一个模板数据库。每当创建一个新的数据库(包括系统数据库的TempDB),会创建一个以 Model 数据库为副本数据库,并更改成你创建数据库时所用的名称。

msdb

msdb 数据库是 SQL Server 代理的数据库,用于配置警报使用 SQL Server 代理和预定作业等。

tempdb

tempddb 数据库是由 SQL Server 用于暂时存储数据的,这其中包含所有临时表,临时存储过程,并通过 SQL Server 生成任何其他临时存储需求。
这些系统数据库有它们特有的用处,系统数据库是我们新建数据库的模板。
SQL Server 是不区分大小写的

索引

参考文献:https://www.cnblogs.com/kissdodog/archive/2013/06/12/3133345.html
https://segmentfault.com/a/1190000016560785

定义

拿汉语字典的目录页(索引)打比方:正如汉语字典中的汉字按页存放一样,SQL Server中的数据记录也是按页存放的,每页容量一般为4K 。为了加快查找的速度,汉语字(词)典一般都有按拼音、笔画、偏旁部首等排序的目录(索引),我们可以选择按拼音或笔画查找方式,快速查找到需要的字(词)。

同理,SQL Server允许用户在表中创建索引,指定按某列预先排序,从而大大提高查询速度。

索引:是SQL Server编排数据的内部方法。它为SQL Server提供一种方法来编排查询数据 。
索引页:数据库中存储索引的数据页;索引页类似于汉语字(词)典中按拼音或笔画排序的目录页。

分类

唯一索引

唯一索引不允许两行具有相同的索引值。
提示:创建了唯一约束,将自动创建唯一索引。尽管唯一索引有助于找到信息,但为了获得最佳性能,建议使用主键约束或唯一约束。

主键索引

为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的,并且不能为空。

在数据库关系图中为表定义一个主键将自动创建主键索引,主键索引是唯一索引的特殊类型。主键索引要求主键中的每个值是唯一的。当在查询中使用主键索引时,它还允许快速访问数据。

聚集索引(Clustered)

表中各行的物理顺序与键值的逻辑(索引)顺序相同,每个表只能有一个。例如:汉语字(词)典默认按拼音排序编排字典中的每页页码。拼音字母a,b,c,d……x,y,z就是索引的逻辑顺序,而页码1,2,3……就是物理顺序。默认按拼音排序的字典,其索引顺序和逻辑顺序是一致的。即拼音顺序较后的字(词)对应的页码也较大。如拼音“ha”对应的字(词)页码就比拼音“ba” 对应的字(词)页码靠后。

非聚集索引(Non-clustered)

非聚集索引指定表的逻辑顺序。数据存储在一个位置,索引存储在另一个位置,索引中包含指向数据存储位置的指针。可以有多个,小于249个。

如果不是聚集索引,表中各行的物理顺序与键值的逻辑顺序不匹配。聚集索引比非聚集索引(nonclustered index)有更快的数据访问速度。例如,按笔画排序的索引就是非聚集索引,“1”画的字(词)对应的页码可能比“3”画的字(词)对应的页码大(靠后)。

提示:SQL Server中,一个表只能创建1个聚集索引,多个非聚集索引。设置某列为主键,该列就默认为聚集索引

作用

通过使用索引,可以大大提高数据库的检索速度,改善数据库性能。

优点

1、 通过创建唯一索引,可以保证数据库表的每一行数据的唯一性。
2、 可以大大加快数据的查询速度,这也是创建索引的最主要的原因。
3、 实现数据的参照完整性,可以速表和表之间的连接。
4、 在使用分组和排序子句进行查询时,也可以显著减少查询中分组和排序的时间。

缺点

1、 创建索引和维护索引要耗费时间,并且随着数据量的增加所耗费的时间也会增加。
2、 索引需要占磁盘空间,除了数据表占数据空间之外,每一个索引还要占一定的物理空间,如果有大量的索引,索引文件可能比数据文件更快达到做大文件尺寸。
3、 当对表中的数据进行增加,删除和修改的时候,索引也要动态地维护,这样就就降低了数据的维护速度。

创建索引的原则

1、 该列用于频繁搜索。
2、 该列用于对数据进行排序。
3、 请不要使用下面的列创建索引:
3.1、列中仅包含几个不同的值。
3.2、表中仅包含几行。为小型表创建索引可能不太划算,因为SQL Server在索引中搜索数据所花的时间比在表中逐行搜索所花的时间更长。

创建索引

CREATE   [UNIQUE]   [CLUSTERED | NONCLUSTERRED]
INDEX    index_name   ON {table | view }(column [ASC | DESC ]  [,...n])
[ INCLUDE ( column_name [ ,...n])]
[with 
(
PAD_INDEX={ON | OFF}
|  FILLFACTOR =fillfactor
|  SORT_IN_TEMPDB={ ON | OFF}
|  IGNORE_DUP_KEY ={ ON  | OFF}
|  STATISRICS_NORECOMPUTE ={ ON | OFF}
|   DROP_EXISTING = { ON | OFF}
|  ONLINE ={ ON | OFF}
|  ALLOW_ROW_LOCKS ={ ON | OFF}
|  ALLOW_PAGE_LOCKS={ ON   | OFF}
|  MAXDOP =max_degree_of_parallelism
)  [,...n]]

UNIQUE:表示在表或视图上创建唯一索引。唯一索引不允许两行具有相同的索引键值。视图的聚集索引必须唯一。

CLUSTERED:表示创建聚集索引,在创建任何非聚集索引之前创建聚集索引,创建聚集索引时会重新生成表中现有的非聚集索引。如果没有指定CLUSTERED,则创建非聚集索引。

NONCLUSTERED:表示创建一个非聚集索引,非聚集索引数据行的物理顺序独立于与索引排序,每个表最多可包含999个非聚集索引,NONCLUSTERED是CREATE INDEX的默认值。

index_name:指定索引的名称,索引名称在表或视图中必须唯一,但在数据库中可不必唯一。

ON{table | view }:指定索引所属的表或视图。

Column:指定索引基于一列或者多列。指定两个或者多个列名,可为指定的列的组合值创建组合索引,{table | view}后的括号中,按排序优先级列出组合索引要包括的列。一个组合索引键中最多可组合16列。组合索引键中的所有列必须在同一个表或视图中。

INCLUDE(column[,…n]):指定要添加到非聚集索引的叶级别的非键列。

PAD_INDEX:表示指定索引填充,默认值为OFF。ON值表示fillfactor指定的可用空间百分比应用于索引的中间级页。

FILLFACTOR=fillfactor:制定一个百分比,表示在索引创建或重新生成过程中数据库引擎应使每个索引页的叶级别达到的填充程度。fillfactor必须为介于1至100直接的整数值,默认值为0;

SORT_IN_TESTDB:指定是否在tempdb中存储临时排序结果,默认值为OFF,ON值表示在tempdb中存储用于生成索引的中间排序结果,OFF表示中间排序结果与索引存储在同一数据库中。

IGNORE_DUP_KEY:指定唯一聚集索引或唯一非聚集索引执行多行插入操作时,出现重复键值的错误响应。默认值为OFF。ON表示发出一跳警告消息,但只有违反了唯一索引的行才会失败,OFF表示发出错误消息,并回滚整个INSERT事物。

STATISRICS_NORECOMPUTE:指定是否重新计算分发统计信息,默认值为OFF。ON表示不会自动重新计算过时的统计信息,OFF表示启用统计信息自动更新功能。

DROP_EXISTING:指定删除并重新生成已命名的先前存在的聚集或非聚集索引。默认值为OFF。ON表示删除并重新生成现有索引。指定的索引名称必须与当前现有的索引相同,但可以修改索引定义,例如:可以指定不同的列,排序顺序,分区方案或索引选项。OFF表示如果指定的索引名已存在,则会显示一条错误。

ONLINE={ON | OFF}:指定在索引操作期间,基础表和关联的索引是否用于查询和数据修改操纵,默认值为OFF。

ALLOW_ROW_LOCKS:指定是否允许行锁,默认值为ON,ON表示在访问索引时允许行所。数据库引擎确定何时使用行锁。OFF表示未使用行锁。

ALLOW_PAGE_LOCKS:指定是否允许页锁,默认值为ON,ON表示在访问索引时允许页锁。数据库引擎确定何时使用页锁。OFF表示未使用页锁。

MAXDOP:指定在索引操作期间,覆盖【最大并行度】配置选项,使用MAXDOP可以限制在执行并行计划的过程中使用的处理器数量,最大数量为64.

【例】在teacher表中的t_phone列上,创建一个名称为Idx_phone的唯一聚集索引,降序排列,填充因子为30%,输入语句如下:

CREATE  UNIQUE  CLOSTERED  INDEX  Idx_phone
ON  teacher (t_phone  DESC)
WITH
FILLFACTOR=30;

修改索引

ALTER INDEX {<name of index> | ALL}
ON<table or view name>
{ REBUILD
[[ WITH (
[PAD_INDEX = {ON | OFF}]
| [[,] FILLFACTOR = <fillfactor>
| [[,] SORT_IN_TEMPDB = { ON | OFF }]
| [[,] IGNORE_DUP_KEY = { ON | OFF }]
| [[,] STATISTICS_NORECOMPUTE = { ON | OFF }]
| [[,] ONLINE = { ON| OFF }]
| [[,] ALLOW_ROW_LOCKS = { ON | OFF }]
| [[,] ALLOW_PAGE_LOCKS = { ON | OFF }]
| [[,] MAXDOP = <max degree of parallelism>
)]
|[ PARTITION = <partition number>
[ WITH (< partition rebuild index option>
[,...N])]]]
| DISABLE
| REORGANIZE
[ PARTITION = <partition number> ]
[ WITH (LOB_COMPACTION = { ON | OFF })]
| SET ([ ALLOW_ROW_LOCKS = { ON | OFF} ]
| [[,] ALLOW_PAGE_LOCKS = { ON | OFF } ]
| [[,] IGNORE_DUP_KEY = { ON | OFF } ]
| [[,] STATISTICS_NORECOMPUTE = { ON | OFF }]
)
}[;]

删除索引

DROP  INDEX  '[table | view ].  index' [,...n]
或者
DROP  INDEX    ' index'  ON   '[table | view ].index' 

index:用于指定要删除的索引名称。

注意:DROP INDEX 命令不能删除由 CREATE TABLE或者ALTER TABLE命令创建的主键(PRIMARY KEY)或者唯一性(UNIQUE)约束索引,也不能删除系统表重的索引。

【例】删除表teacher中的索引 multi_index,如下:

USE  sample_db;
GO
exec   sp_helpindex   'teacher'
DROP   INDEX   teacher.multi_index
Exec    sp_helpindex   'teacher';

查看索引

用系统存储过程查看索引信息
系统存储过程sp_helpindex可以返回某个表或视图中的索引信息,语法如下:
sp_helpindex [@objectname= ] ‘name’;

[@objectname=] ‘name’:用户定义的表或视图的限定或非限定名称。仅当指定限定的表或视图名称时,才需要使用引号。如果提供了完全限定的名称,包括数据库名称,则该数据库名称必须是当前数据库的名称。

【例】使用存储过程查看是 sample_db数据库中teacher表中定义的索引信息,输入语句如下。

USE  sample_db; 
GO
exec sp_helpindex 'teacher';

视图

从用户角度来看,一个视图是从一个特定的角度来查看数据库中的数据 。

从数据库系统内部来看,一个视图是由 SELECT 语句组成的查询定义的虚拟表(因为一个视图可以拉动多个表,并汇总数据在一起并将其显示,就好像它是一个单一的表)

视图是由一张或多张表中的数据组成的,当你运行视图,会看到它的结果,就像打开一个表时一样。

从数据库系统外部来看,视图就如同一张表一样,对表能够进行的一般操作都可以应用于视图,例如查询,插入,修改,删除操作等。但是视图属于虚拟表,只能查询数据,不能对其数据进行修改,插入,删除等操作。

创建视图

通过使用 CREATE VIEW 语句创建一个视图,其次是 SELECT 语句,如下:

CREATE  VIEW  ViewName  AS
SELECT ...

查询视图

查询视图就像是查询数据库表数据一样。 如下:

SELECT  *  FROM  ViewName;

修改视图

通过使用 ALTER 修改现有的视图,而不是 CREATE。

如果我们想要更改视图就要使用 StatusName 字段,而不是 StatusId,做法如下:

ALTER VIEW ToDoList AS
SELECT	Tasks.TaskName, Tasks.Description
FROM	Status INNER JOIN
			Tasks ON Status.StatusId = Tasks.StatusId
WHERE	(Status.StatusName = 'To Do')

删除视图

drop  view  ViewName;

注:使用查询设计器也可以右键单击视图,然后选择设计来修改您的视图。
正如你所看到的,视图让您保存查询,以便可以做一个 SELECT,再次运行它也会比较简单。
但它们的确有其局限性:它们允许选择数据,但不允许执行任何业务逻辑,如条件语句等。

存储过程

参考文献:https://www.w3cschool.cn/sql/sql-storage.html

视图通过简单的SELECT查询来解决复杂的查询,但是视图不能提供业务逻辑功能,而存储过程可以办到这点。

定义

存储过程 Procedure 是一组为了完成特定功能的 SQL 语句集合,经编译后存储在数据库中,用户通过指定存储过程的名称并给出参数来执行。

存储过程中可以包含逻辑控制语句和数据操纵语句,它可以接受参数、输出参数、返回单个或多个结果集以及返回值。

由于存储过程在创建时即在数据库服务器上进行了编译并存储在数据库中,所以存储过程运行要比单个的 SQL 语句块要快。同时由于在调用时只需用提供存储过程名和必要的参数信息,所以在一定程度上也可以减少网络流量、简单网络负担。

优点

1、 存储过程只在创造时进行编译,以后每次执行存储过程都不需再重新编译,而一般SQL语句每执行一次就编译一次,所以使用存储过程可提高数据库执行速度,效率要比T-SQL语句高。
2、 当对数据库进行复杂操作时,可将此复杂操作用存储过程封装起来与数据库提供的事务处理结合一起使用。
3、 一个存储过程在程序在网络中交互时可以替代大堆的T-SQL语句,所以也能降低网络的通信量,提高通信速率。
4、 存储过程可以重复使用,可减少数据库开发人员的工作量。
5、 安全性高,可设定只有某些用户才具有对指定存储过程的使用权。
在这里插入图片描述

创建存储过程

我们需要使用 CREATE PROCEDURE 语句创建一个存储过程,接着要补充存储过程的代码,如果存储过程将要接受参数,它们需要被包括在名称后,如下:

CREATE  PROCEDURE  ProcedureName  AS
OR
CREATE  PROCEDURE  ProcedureName  @{Parameter Name} {data type}  AS

执行存储过程

创建了存储过程后,要在任何时候执行它,可以执行或者调用 EXEC。如果存储过程的参数要求提供这些程序名在后面,像这样:

EXECUTE  ProcedureName 
EXEC  ProcedureName  
EXEC  ProcedureName  @Parameter = 5

修改存储过程

如果需要修改现有的存储过程,只需更换掉 CREATE ,使用 ALTER。

我们在 “Latest” 和 “Tasks”间添加一个空格(即“Latest Tasks”),并添加描述字段,如下:

ALTER PROCEDURE  ProcedureName  @Count int AS
SET ROWCOUNT @Count
SELECT TaskName AS "Latest Tasks", Description, DateCreated
FROM Tasks
ORDER BY DateCreated DESC

删除存储过程

drop  procedure  ProcedureName ;

触发器

定义

触发器是一种特殊类型的存储过程,它在您使用一种或多种数据修改操作(UPDATE、INSERT 或 DELETE)来修改指定表中的数据时运行。

优点

1、 触发器是自动的。当对表中的数据做了任何修改之后立即被激活。
2、 触发器可以通过数据库中的相关表进行层叠修改。
3、 触发器可以强制限制。这些限制比用CHECK约束所定义的更复杂。与CHECK约束不同的是,触发器可以引用其他表中的列。

作用

触发器的主要作用就是其能够实现由主键和外键所不能保证的复杂参照完整性和数据的一致性,它能够对数据库中的相关表进行级联修改,提高比CHECK约束更复杂的的数据完整性,并自定义错误消息。触发器的主要作用主要有以下接个方面:
1、 强制数据库间的引用完整性。
2、 级联修改数据库中所有相关的表,自动触发其它与之相关的操作。
3、 跟踪变化,撤销或回滚违法操作,防止非法修改数据。
4、 返回自定义的错误消息,约束无法返回信息,而触发器可以。
5、 触发器可以调用更多的存储过程。

分类

DML(数据操作语言,Data Manipulation Language)触发器

DML触发器是一些附加在特定表或视图上的操作代码,当数据库服务器中发生数据操作语言事件时执行这些操作。SQL Server中的DML触发器有三种:
1、 insert触发器: 向表中插入数据时被触发;
2、 delete触发器:从表中删除数据时被触发;
3、 update触发器:修改表中数据时被触发。

DDL(数据定义语言,Data Definition Language)触发器

DDL触发器是当服务器或者数据库中发生数据定义语言(主要是以create,drop,alter开头的语句)事件时被激活使用,使用DDL触发器可以防止对数据架构进行的某些更改或记录数据中的更改或事件操作。

登录触发器

登录触发器将为响应 LOGIN 事件而激发存储过程。与SQL Server实例建立用户会话时将引发此事件。登录触发器将在登录的身份验证阶段完成之后且用户会话实际建立之前激发。因此,来自触发器内部且通常将到达用户的所有消息(例如错误消息和来自PRINT语句的消息)会传送到SQL Server错误日志。如果身份验证失败,将不激发登录触发器。

注意

Instead of 和 After触发器。这两种触发器的差别在于他们被激活的同:
Instead of触发器用于替代引起触发器执行的T-SQL语句。除表之外,Instead of 触发器也可以用于视图,用来扩展视图可以支持的更新操作。
After触发器在一个Insert,Update或Deleted语句之后执行,进行约束检查等动作都在After触发器被激活之前发生。After触发器只能用于表。
一个表或视图的每一个修改动作(insert,update和delete)都可以有一个instead of 触发器,一个表的每个修改动作都可以有多个After触发器。

工作原理

触发器触发时,系统自动在内存中创建临时表(inserted表或者deleted表);该表只读,不允许修改,触发器执行完成后,自动删除临时表。
在这里插入图片描述

创建触发器

CREATE   TRIGGER   TriggerName
  ON   { TableName | ViewName }
[ WITH ENCRYPTION ]  //用于加密触发器 ,可以省略
{  FOR  | AFTER  |  INSTEAD  OF }   [INSERT | UPDATE | DELETE]
AS
BEGIN 
/*  执行的sql 语句  */
END 

修改触发器

ALTER   TRIGGER   TriggerName
  ON   { TableName | ViewName }
[ WITH ENCRYPTION ]  //用于加密触发器 ,可以省略
{  FOR  | AFTER  |  INSTEAD  OF }   [INSERT | UPDATE | DELETE]
AS
BEGIN 
/*  执行的sql 语句  */
END 

禁用触发器

DISABLE  TRIGGER  TriggerName
  ON   { TableName | ViewName }

启用触发器

ENABLE  TRIGGER  TriggerName
  ON   { TableName | ViewName }

查询已存在的触发器

select * from sys.triggers;
select * from sys.objects where type = 'TR';

查看触发器触发事件

select  te.* , t.* from sys.trigger_events te 
join sys.triggers t  on t.object_id = te.object_id

查看创建触发器语句

exec  sp_helptext  'trigger_name';

删除触发器

drop trigger trigger_name

作业

参考文献:https://www.cnblogs.com/kerrycode/p/3279559.html
创建/修改 定时作业:https://jingyan.baidu.com/article/adc81513be3423f722bf7351.html
查看 定时作业 执行历史记录:
https://jingyan.baidu.com/article/0f5fb099efaa2c6d8334eae5.html

备份:https://jingyan.baidu.com/article/46650658e78e82f549e5f8c8.html
自动备份:https://www.cnblogs.com/punkrocker/p/11337149.html
备份/还原:https://docs.microsoft.com/zh-cn/sql/relational-databases/backup-restore/back-up-and-restore-of-sql-server-databases?view=sql-server-ver15

同步(一主多从)

项目读写分离,修改主表数据,同步从表数据
参考文献:https://jingyan.baidu.com/article/73c3ce2844c43be50343d9d4.html
https://blog.csdn.net/weixin_34146410/article/details/92407244?utm_medium=distribute.pc_relevant.none-task-blog-baidujs-5
https://www.cnblogs.com/zhengcheng/p/4492423.html

注意:后期文档需要提交

链接服务器

参考文献:https://www.w3cschool.cn/sqlserver/sqlserver-xy1g28p7.html

SQL Server 中存在可以链接到其他服务器的选项,一般情况下是用来与别的 SQL Server 数据库相连接,但是有时候也可以与一个Microsoft Access数据库 相连接。这样的操作是通过链接服务器节点实现的。

链接服务器节点可以连接到另一个数据库,通常/通常在不同的机器上运行,也许在不同的城市/国家。如果您需要执行分布式查询(查询远程数据库),这可能是有用的。

设置链接服务器就是相当于使用简单的 SQL Server 管理套件,所有需要的就是查询远程服务器的详细信息,以及数据库。

创建链接服务器

exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 '
exec sp_addlinkedsrvlogin 'ITSV ', 'false ',null, '用户名 ', '密码 '

查询示例

select * from ITSV.数据库名.dbo.表名

导入示例

select * into 表 from ITSV.数据库名.dbo.表名

以后不再使用时删除链接服务器

exec sp_dropserver 'ITSV ', 'droplogins '

连接远程/局域网数据

openrowset

查询示例:

select * from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)

生成本地表:

select * into 表 from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)

把本地表导入远程表:

insert openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)
select *from 本地表

更新本地表:

update b
set b.列A=a.列A
from openrowset( 'SQLOLEDB ', 'sql服务器名 '; '用户名 '; '密码 ',数据库名.dbo.表名)as a inner join 本地表 b
on a.column1=b.column1

openquery

首先创建一个连接创建链接服务器

exec sp_addlinkedserver 'ITSV ', ' ', 'SQLOLEDB ', '远程服务器名或ip地址 '

查询

select *
FROM openquery(ITSV, 'SELECT * FROM 数据库.dbo.表名 ')

把本地表导入远程表

insert openquery(ITSV, 'SELECT * FROM 数据库.dbo.表名 ')
select * from 本地表

更新本地表

update b
set b.列B=a.列B
FROM openquery(ITSV, 'SELECT * FROM 数据库.dbo.表名 ') as a
inner join 本地表 b on a.列A=b.列A

opendatasource/openrowset

SELECT *
FROM opendatasource( 'SQLOLEDB ', 'Data Source=ip/ServerName;User ID=登陆名;Password=密码' ).test.dbo.roy_ta

把本地表导入远程表

insert opendatasource( 'SQLOLEDB ', 'Data Source=ip/ServerName;User ID=登陆名;Password=密码 ').数据库.dbo.表名
select * from 本地表

SQL 语句

参考文献:https://www.w3cschool.cn/sql/sql-sentence.html

变量

局部变量

declare  @id char(10)   -- 声明
set @id = ‘01’
select  @id = ‘02’ –  赋值

全局变量

全局变量声明必须以@@开头

判断语句

IF ELSE

if  判断条件
执行语句
else if 判断条件
执行语句
else 执行语句

CASE

 CASE 
 WHEN  条件 then  执行语句
 WHEN  条件 then  执行语句
else 语句
end

循环 while

WHILE 条件
BEGIN 
  执行
END 

复制表(只复制结构,源表名:a 新表名:b) (Access可用)

方法一:select * into b from a where 1<>1
方法二:select top 0 * into b from a

拷贝表(拷贝数据,源表名:a 目标表名:b) (Access可用)

insert into b(a, b, c) select d,e,f from a;

跨数据库之间表的拷贝(具体数据使用绝对路径)(Access可用)

insert into b(a, b, c) select d,e,f from b in ‘具体数据库’ where 条件 
例子:..from b in '"&Server.MapPath(".")&"\data.mdb" &"' where..

初始化表table1

此sql 只删除表数据 不更改表结构

TRUNCATE  ABLE   ble1

删除数据库表

DROP  ABLE  ableName 

分页

select top 10 b.* from (select top 20 主键字段,排序字段 from 表名 order by 排序字段 desc) a,表名 b where b.主键字段 = a.主键字段 order by a.排序字段

数据库分页:

declare @start int,@end int
@sql nvarchar(600)
set @sql=’select top’+str(@end-@start+1)+’+from T where rid not in(select top’+str(@str-1)+’Rid from T where Rid>-1)’
exec sp_executesql @sql

注意:在top后不能直接跟一个变量,所以在实际应用中只有这样的进行特殊的处理。Rid为一个标识列,如果top后还有具体的字段,这样做是非常有好处的。因为这样可以避免
top的字段如果是逻辑索引的,查询的结果后实际表中的不一致(逻辑索引中的数据有可能和数据表中的不一致,而查询时如果处在索引则首先查询索引)

N到M条记录(要有主索引ID)

Select Top M-N * From 表 Where ID in (Select Top M ID From 表) Order by ID Desc 

例:一张表有一万多条记录,表的第一个字段 RecID 是自增长字段, 写一个SQL语句, 找出表的第31到第40个记录。

select top 10 b.*  from ( select  top  40  a.*  from a order by a.recid ) b  order by b.recid desc 

并集 UNION 运算符

UNION 运算符通过组合其他两个结果表(例如 TABLE1 和 TABLE2)并消去表中任何重复行而派生出一个结果表。当 ALL 随 UNION一起使用时(即 UNION ALL),不消除重复行。两种情况下,派生表的每一行不是来自 TABLE1 就是来自 TABLE2。

交集 INTERSECT

INTERSECT 运算符通过只包括 TABLE1 和 TABLE2 中都有的行并消除所有重复行而派生出一个结果表。当 ALL 随 INTERSECT 一起使用时 (INTERSECT ALL),不消除重复行。

去重 EXCEPT

EXCEPT 运算符通过包括所有在 TABLE1 中但不在 TABLE2 中的行并消除所有重复行而派生出一个结果表。当 ALL 随 EXCEPT 一起使用时 (EXCEPT ALL),不消除重复行。

例:包括所有在 TableA 中但不在 TableB和TableC 中的行并消除所有重复行而派生出一个结果表

(select a from tableA ) except (select a from tableB) except (select a from tableC)

ROW_NUMBER()

说明:返回结果集分区内行的序列号,每个分区的第一行从1开始。
语法:ROW_NUMBER () OVER ([ <partition_by_clause> ] <order_by_clause>) 。
备注:ORDER BY 子句可确定在特定分区中为行分配唯一 ROW_NUMBER 的顺序。
参数:<partition_by_clause> :将 FROM 子句生成的结果集划入应用了 ROW_NUMBER 函数的分区。
<order_by_clause>:确定将 ROW_NUMBER 值分配给分区中的行的顺序。
返回类型:bigint 。
例:统计每一个客户最近下的订单是第几次下的订单。

with tabs as 
( 
select ROW_NUMBER() over(partition by customerID  order by totalPrice) as rows,customerID,totalPrice, DID from OP_Order 
 ) 
select MAX(rows) as '下单次数',customerID from tabs group by customerID
   

备注:此文章内容来源w3cschool教程,如有问题,请评论指教!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章