Select
From
Where
Group by
Having
Order by
Null
Like
ESCAPE 'escape_ character'
允许在字符串中搜索通配符,而不是将其作为通配符使用。escape_character 是放在通配符前表示此特殊用法的字符。
例:
select * from course
where cname like 'cssa_%' escape 'a'
会得到’css_’打头的所有行
Cube
Case
In
Insert
Update
Delete
Create
Alter
Drop
子查询 in、any、all、exists
联合查询 union、join
查询语句的性能优化
搜索条件 not/and/or
谓词 between/contains/exists/freetext/in/is [not] null/like
一、select子句
语法: SELECT [ ALL | DISTINCT ]
[ TOP n [ PERCENT ] [ WITH TIES ] ]
< select_list >
< select_list > ::= {* | { table_name | view_name | table_alias }.*
| { column_name | expression | IDENTITYCOL | ROWGUIDCOL }
[ [ AS ] column_alias ]| column_alias = expression } [ ,...n ]
参数:
ALL 指定结果集中可以显示重复行。是默认设置
DISTINCT 指定在结果集中只能显示唯一行。空值被认为是相等的
TOP n [PERCENT] 指定从结果集中输出前n行。n 是介于 0 和 4294967295 之间的整数。如果还指定了 PERCENT,则只从结果集中输出前百分之 n 行。当指定时带 PERCENT 时,n 必须是介于 0 和 100 之间的整数。
如果查询包含 ORDER BY 子句,将输出由 ORDER BY 子句排序的前 n 行(或前百分之 n
行)。如果查询没有 ORDER BY 子句,行的顺序将任意。
WITH TIES 指定从基本结果集中返回附加的行,这些行包含与出现在 TOP n (PERCENT) 行最后的 ORDER BY 列中的值相同的值。如果指定了 ORDER BY 子句,则只能指定 TOP ...WITH TIES。
<select_list> 为结果集选择的列。
<select_list> ::= 选择列表是以逗号分割的一系列表达式。
* 指定在FRPM子句中内返回的所有表和视图内的所有列。列按FROM子句所指定的由表或视图返回,并按它们在表或视图内的顺序返回
Table_name | view_name | table_alias 将 * 的作用限制为指定的表或视图。 Cloumn_name 要返回的列名。要限定列名,以避免二义性引用。参照FROM子句
Expression 是列名、常量、函数以及由运算符连接的列名、常量和函数的任意组合,或者是子查询。
IDENTITYCOL 返回标识列。如果FROM子句中的多个表内包含标识列,那么就要避免二义性引用来对标识列加以限定。具体方法参照ROWGUIDCOL。
ROWGUIDCOL 返回行全局唯一标识列。如果在From子句中多个表包含ROWGUIDCOL属性列,则必须通过特定的表名来限定(例如:T1.ROWGUIDCOL)ROWGUIDCOL。
Column_alias 是查询结果集内替换列名的可选名。例如:可以为名为‘sanme’指定别名,如‘姓名’。
别名还可以为表达式的结果指定名称,例如:
select AVG (grade) as '平均分' from sc
备注:column_alias 可用于ORDER BY子句。但是不能用于WHERE、GROUP BY或HAVING子句。如果查询表达式是DECLARE CURSOR语句一部分,则column_alias不能用在FOR UPDATE子句中。
Select子句是select语句的开始部分,它限定了查询结果返回的列
通常情况下不要使用 * 关键字来返回所有列,除非有明确的需求要查询所有字段,因为 * 关键字会大大降低查询的效率,一般应指名具体的查询列。
当输入的字段名包括空格和标点符号时,用方括号把它括起来
例如:要查询表student中前5条记录,要求返回两列数据:学生姓名和所在系 select top 5 sname as '姓名',sdept as '所在系' from student
WHERE、GROUP BY 和 HAVING 子句的处理顺序
以下步骤显示带 WHERE 子句、GROUP BY 子句和 HAVING 子句的 SELECT 语句的处理顺序:
1、FROM 子句返回初始结果集。
2、WHERE 子句排除不满足搜索条件的行。
3、GROUP BY 子句将选定的行收集到 GROUP BY 子句中各个唯一值的组中。
4、选择列表中指定的聚合函数可以计算各组的汇总值。
5、此外,HAVING 子句排除不满足搜索条件的行。
二、from子句 语法:
From <table_source>
参数
<table_source>
指定要在 Transact-SQL 语句中使用的表、视图或派生表源(有无别名均可)。虽然语句中可用的表源个数的限值根据可用内存和查询中其他表达式的复杂性而有所不同,但一个语句中最多可使用 256 个表源。单个查询可能不支持最多有 256 个表源。可将 table 变
量指定为表源。
注意:
如果查询中引用了许多表,查询性能会受到影响。编译和优化时间也受到其他因素的影响。这些因素包括:每个 <table_source> 是否有索引和索引视图,以及 SELECT 语句中 <select_list> 的大小。
表源在 FROM 关键字后的顺序不影响返回的结果集。如果 FROM 子句中出现重复的名称,SQL Server 会返回错误。
From子句跟在SELECT语句后面,指定要从中查询数据的表,可以是一个表,也可以是视图、派生表或是多个表的联合
当From子句中的两个表中包含重复名的列时,要对列名加上限定。例如,在表sc和course表内都有名为课程号cno列。如果在查询中连接两个表,可以在选择列表中将课程号指定为sc.cno
例如:查询每门课的平均成绩,要求返回课程名与平均分
select cname,AVG (grade) as '平均分' from sc
left join course on sc.cno =course .cno group by course .cname 备注:有诸如sum、avg等聚合函数时候一般要有GROUP BY
三、where子句
语法
[ WHERE <search_condition> ]
参数
< search_condition >
定义要返回的行应满足的条件。对搜索条件中可以包含的谓词数量没有限制。
WHERE是可选的,但是在使用时必须放在FROM之后,用来限定查询结果,只有符合条件的记录才会显示出来。WHERE子句可以是单一条件,也可以是组合而成的复杂条件。
备注: WHERE子句中可以嵌套子查询
四、group by子句
语法 ISO-Compliant Syntax
GROUP BY <group by spec>
<group by spec> ::=
<group by item> [ ,...n ]
<group by item> ::=
<simple group by item>
| <rollup spec>
| <cube spec>
| <grouping sets spec>
| <grand total>
<simple group by item> ::=
<column_expression>
<rollup spec> ::=
ROLLUP ( <composite element list> )
<cube spec> ::=
CUBE ( <composite element list> )
<composite element list> ::=
<composite element> [ ,...n ]
<composite element> ::=
<simple group by item> | ( <simple group by item list> )
<simple group by item list> ::= <simple group by item> [ ,...n ]
<grouping sets spec> ::=
GROUPING SETS ( <grouping set list> )
<grouping set list> ::=
<grouping set> [ ,...n ]
<grouping set> ::=
<grand total>
| <grouping set item>
| ( <grouping set item list> )
<empty group> ::=
( )
<grouping set item> ::=
<simple group by item>
| <rollup spec>
| <cube spec>
<grouping set item list> ::=
<grouping set item> [ ,...n ]
Non-ISO-Compliant Syntax
[ GROUP BY [ ALL ] group_by_expression [ ,...n ]
[ WITH { CUBE | ROLLUP } ]
]
参数
ROLLUP ( )
生成简单的 GROUP BY 聚合行以及小计行或超聚合行,还生成一个总计行。
返回的分组数等于 <composite element list> 中的表达式数加一。例如,下面的语句。 SELECT a, b, c, SUM ( <expression> )
FROM T
GROUP BY ROLLUP (a,b,c)
会为 (a, b, c)、(a, b) 和 (a) 值的每个唯一组合生成一个带有小计的行。还将计算一个总计行。
列是按照从右到左的顺序汇总的。列的顺序会影响 ROLLUP 的输出分组,而且可能会影响结果集内的行数。
CUBE ( )
生成简单的 GROUP BY 聚合行、ROLLUP 超聚合行和交叉表格行。
CUBE 针对 <composite element list> 中表达式的所有排列输出一个分组。
生成的分组数等于 (2n),其中 n = <composite element list> 中的表达式数。例如,下面的语句。
SELECT a, b, c, SUM (<expression>)
FROM T
GROUP BY CUBE (a,b,c)
会为 (a, b, c)、(a, b)、(a, c)、(b, c)、(a)、(b) 和 (c) 值的每个唯一组合生成一个带有小计的行,还会生成一个总计行。
列的顺序不影响 CUBE 的输出。
GROUPING SETS ( )
在一个查询中指定数据的多个分组。仅聚合指定组,而不聚合由 CUBE 或 ROLLUP 生成的整组聚合。其结果与针对指定的组执行 UNION ALL 运算等效。GROUPING SETS 可以包含单个元素或元素列表。GROUPING SETS 可以指定与 ROLLUP 或 CUBE 返回的内容等效的分组。<grouping set item list> 可以包含 ROLLUP 或 CUBE。 ( )
空组生成总计。
WITH CUBE
后续版本的 Microsoft SQL Server 将删除该功能。请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。指定结果集内不仅包含由 GROUP BY 提供的行,同时还包含汇总行。GROUP BY 汇总行针对每个可能的组和子组组合在结果集内返回。使用 GROUPING 函数可确定结果集内的空值是否为 GROUP BY 汇总值。
结果集内的汇总行数取决于 GROUP BY 子句内包含的列数。由于 CUBE 返回每个可能的组和子组组合,因此不论在列分组时指定使用什么顺序,行数都相同。
WITH ROLLUP
后续版本的 Microsoft SQL Server 将删除该功能。请避免在新的开发工作中使用该功能,并着手修改当前还在使用该功能的应用程序。指定结果集内不仅包含由 GROUP BY 提供的行,同时还包含汇总行。按层次结构顺序,从组内的最低级别到最高级别汇总组。组的层次结构取决于列分组时指定使用的顺序。更改列分组的顺序会影响在结果集内生成的行数。
group by子句按一个或多个列或表达式的值将一组选定行组合成一个摘要行集。针对每一组返回一行。SELECT 子句 <select> 列表中的聚合函数提供有关每个组(而不是各行)的信息。
GROUP BY 指出了对查询结果分组的依据,并且如果在SELECT子句中包含聚合函数,则计算每组的汇总值。指定GROUP BY 时,选择列表中任一非聚合表达式内所有列都应包含在GROUP BY列表中,或者GROUP BY 表达式必须与选择列表表达式完全匹配。
备注
GROUP BY 子句中的表达式可以包含 FROM 子句中表、派生表或视图的列。这些列不必显示在 SELECT 子句 <select> 列表中。
<select> 列表中任何非聚合表达式中的每个表列或视图列都必须包括在 GROUP BY 列表中
注意:text、ntext和image类型的数据不能够用于GROUP BY 子句。
SELECT sno, avg( grade)
FROM sc
GROUP BY sno
五、having子句
指定组或聚合的搜索条件。HAVING 只能与 SELECT 语句一起使用。HAVING 通常在 GROUP BY 子句中使用。如果不使用 GROUP BY 子句,则 HAVING 的行为与 WHERE 子句一样。
HAVING和WHERE类似,可用来决定显示哪些记录,在使用GROUP BY对这些记录分组后,HAVING会决定应显示的记录。在HAVING子句中不能使用text、ntext和image数据类型。
SELECT sno, avg( grade) as avg_grade
FROM sc
GROUP BY sno
having avg( grade)>80
六、order by子句
语法 [ ORDER BY
{
order_by_expression
[ COLLATE collation_name ]
[ ASC | DESC ]
} [ ,...n ]
]
参数
order_by_expression
指定要排序的列。可以将排序列指定为一个名称或列别名,也可以指定一个表示该名称或别名在选择列表中所处位置的非负整数。order_by_expression 出现在排名函数中时,不能指定整数。列名和别名可由表名或视图名加以限定。在 SQL Server 中,限定的列名和别名将解析为 FROM 子句中列出的列。如果 order_by_expression 未限定,则该值在 SELECT 语句列出的所有列中必须是唯一的。
COLLATE {collation_name}
指定根据 collation_name 中指定的排序规则,而不是表或视图中所定义的列的排序规则,应执行的 ORDER BY 操作。collation_name 可以是 Windows 排序规则名称或 SQL 排序规则名称。COLLATE 仅适用于 char、varchar、nchar 和 nvarchar 数据类型的列。
ASC
指定按升序,从最低值到最高值对指定列中的值进行排序。默认为升序。
DESC
指定按降序,从最高值到最低值对指定列中的值进行排序。
SELECT sno, avg( grade) as avg_grade
FROM sc
GROUP BY sno
having avg( grade)>80
order by sno desc
七、insert语句
语法 [ WITH <common_table_expression> [ ,...n ] ]
INSERT
[ TOP ( expression ) [ PERCENT ] ]
[ INTO ]
{ <object> | rowset_function_limited
[ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
}
{
[ ( column_list ) ]
[ <OUTPUT Clause> ]
{ VALUES ( ( { DEFAULT | NULL | expression } [ ,...n ] ) [ ,...n ] )
| derived_table
| execute_statement
| <dml_table_source>
| DEFAULT VALUES
}
}
[; ]
<object> ::=
{
[ server_name . database_name . schema_name .
| database_name .[ schema_name ] .
| schema_name .
]
table_or_view_name
}
<dml_table_source> ::=
SELECT <select_list>
FROM ( <dml_statement_with_output_clause> )
[AS] table_alias [ ( column_alias [ ,...n ] ) ]
[ WHERE <search_condition> ]
[ OPTION ( <query_hint> [ ,...n ] ) ]
参数
TOP ( expression ) [ PERCENT ]
指定将插入的随机行的数目或百分比。expression 可以是行数或行的百分比。在和 INSERT、UPDATE 或 DELETE 语句结合使用的 TOP 表达式中引用的行不按任何顺序排列。
在 INSERT、UPDATE 和 DELETE 语句中,需要使用括号分隔 TOP 中的 expression。 INTO
一个可选的关键字,可以将它用在 INSERT 和目标表之间。
VALUES
引入要插入的数据值的列表。对于 column_list(如果已指定)或表中的每个列,都必须有一个数据值。必须用圆括号将值列表括起来。
如果 VALUES 列表中的各值与表中各列的顺序不相同,或者未包含表中各列的值,则必须使用 column_list 显式指定存储每个传入值的列。
若要插入多行值,VALUES 列表的顺序必须与表中各列的顺序相同,且此列表必须包含与表中各列或 column_list 对应的值以便显式指定存储每个传入值的列。可以在单个 INSERT 语句中插入的最大行数为 1000。若要插入超过 1000 行的数据,请创建多个 INSERT 语句,或者通过使用 bcp 实用工具或 BULK INSERT 语句大容量导入数据。
DEFAULT
强制数据库引擎加载为列定义的默认值。如果某列并不存在默认值,并且该列允许 Null 值,则插入 NULL。对于使用 timestamp 数据类型定义的列,插入下一个时间戳值。DEFAULT 对标识列无效。
INSERT语句用来向表中追加数据,可以以此追加一行数据,也可以从另外的表或查询中追加数据,配合OPENROWSE可以从其他的数据库系统中追加数据。
INSERT将一行新的数据追加到表中,但是如果INSERT语句违反约束或规则,或者它有列的数据与类型不兼容的值,那么该语句就会失败。
可以使用INSERT…SELECT语句从其他表或视图添加数据,该语句对于批量添加特别有效。必须保证目标表的字段个数,顺序与来源表的字段个数、顺序完全一致,并且添加到新表中要符合数据完整性约束。(用SELECT…INTO也能实现这样的效果)
八、update语句
语法 [ WITH <common_table_expression> [...n] ]
UPDATE
[ TOP ( expression ) [ PERCENT ] ]
{ <object> | rowset_function_limited
[ WITH ( <Table_Hint_Limited> [ ...n ] ) ]
}
SET
{ column_name = { expression | DEFAULT | NULL }
| { udt_column_name.{ { property_name = expression
| field_name = expression }
| method_name ( argument [ ,...n ] )
}
}
| column_name { .WRITE ( expression , @Offset , @Length ) }
| @variable = expression
| @variable = column = expression
| column_name { += | -= | *= | /= | %= | &= | ^= | |= } expression
| @variable { += | -= | *= | /= | %= | &= | ^= | |= } expression
| @variable = column { += | -= | *= | /= | %= | &= | ^= | |= } expression } [ ,...n ]
[ <OUTPUT Clause> ]
[ FROM{ <table_source> } [ ,...n ] ]
[ WHERE { <search_condition>
| { [ CURRENT OF
{ { [ GLOBAL ] cursor_name }
| cursor_variable_name
}
]
}
}
]
[ OPTION ( <query_hint> [ ,...n ] ) ]
[ ; ]
<object> ::=
{
[ server_name . database_name . schema_name .
| database_name .[ schema_name ] .
| schema_name .
]
table_or_view_name}
参数
SET
指定要更新的列或变量名称的列表。
column_name
包含要更改的数据的列。column_name 必须已存在于 table_or view_name 中。 不能更新标识列。
DEFAULT
指定用为列定义的默认值替换列中的现有值。 如果该列没有默认值并且定义为允许 Null 值,则该参数也可用于将列更改为 NULL。
WHERE
指定条件来限定所更新的行。 根据所使用的 WHERE 子句的形式,有两种更新形式: 搜索更新指定搜索条件来限定要删除的行。
定位更新使用 CURRENT OF 子句指定游标。 更新操作发生在游标的当前位置。
UPDATE语句用于更新一个表中选定行的一列或多列的值。要更新的目标表在语句中定义,SET子句则指定要更新那些列并计算它们的值。UPDATE语句总是包含WHERE语句。因为UPDATE语句具有不可逆转性,所以要慎用。
利用WHERE子句,可以使用UPDATE语句更新符合条件的记录,如果该条件来自于其它的表,则可以利用子查询来指定外部条件。
九、delete语句
语法 [ WITH <common_table_expression> [ ,...n ] ]
DELETE
[ TOP ( expression ) [ PERCENT ] ]
[ FROM ]
{ <object> | rowset_function_limited
[ WITH ( <table_hint_limited> [ ...n ] ) ]
}
[ <OUTPUT Clause> ]
[ FROM <table_source> [ ,...n ] ]
[ WHERE { <search_condition>
| { [ CURRENT OF
{ { [ GLOBAL ] cursor_name }
| cursor_variable_name
}
]
}
}
]
[ OPTION ( <Query Hint> [ ,...n ] ) ]
[; ]
<object> ::=
{
[ server_name.database_name.schema_name.
| database_name. [ schema_name ] .
| schema_name.
]
table_or_view_name
}
参数
WHERE
指定用于限制删除行数的条件。如果没有提供 WHERE 子句,则 DELETE 删除表中的所有行。
基于 WHERE 子句中所指定的条件,有两种形式的删除操作:
搜索删除指定搜索条件以限定要删除的行。例如,WHERE column_name = value。
定位删除使用 CURRENT OF 子句指定游标。删除操作在游标的当前位置执行。这比使用 WHERE search_condition 子句限定要删除的行的搜索 DELETE 语句更为精确。如果搜索条
件不唯一标识单行,则搜索 DELETE 语句删除多行。
DELETE用于从表中删除数据,可以与WHERE子句配合使用,用于删除符合条件的记录。当使用DELETE删除记录后,不能取消此操作。如果想要知道哪些记录已被删除,建议首先验证使用相同条件的选定查询的结果。
注意:如果要删除表中的所有行,则TRUNCATE TABLE 比DELETE快。DELETE以物理方式一次删除一行,并在事务日志中记录每个删除的行。TRUNCATE TABLE 则释放所有与表关联的页。因此TRUNCATE TABLE比DELETE快且需要的事务日志空间更少。TRUNCATE TABLE在功能上与不带WHERE子句的DELETE相当。
与 DELETE 语句相比,TRUNCATE TABLE 具有以下优点:
1.所用的事务日志空间较少。
DELETE 语句每次删除一行,并在事务日志中为所删除的每行记录一个项。TRUNCATE TABLE 通过释放用于存储表数据的数据页来删除数据,并且在事务日志中只记录页释放。
2.使用的锁通常较少。
当使用行锁执行 DELETE 语句时,将锁定表中各行以便删除。TRUNCATE TABLE 始终锁定表和页,而不是锁定各行。
3.如无例外,在表中不会留有任何页。
执行 DELETE 语句后,表仍会包含空页。例如,必须至少使用一个排他 (LCK_M_X) 表锁,才能释放堆中的空表。如果执行删除操作时没有使用表锁,表(堆)中将包含许多空页。对于索引,删除操作会留下一些空页,尽管这些页会通过后台清除进程迅速释放。
TRUNCATE TABLE 删除表中的所有行,但表结构及其列、约束、索引等保持不变。若要删除表定义及其数据,请使用 DROP TABLE 语句。
如果表包含标识列,该列的计数器重置为该列定义的种子值。如果未定义种子,则使用默认值 1。若要保留标识计数器,请使用 DELETE。
不能对以下表使用 TRUNCATE TABLE:
1.由 FOREIGN KEY 约束引用的表。(您可以截断具有引用自身的外键的表。)
2.参与索引视图的表。
3.通过使用事务复制或合并复制发布的表。
对于具有以上一个或多个特征的表,请使用 DELETE 语句。
TRUNCATE TABLE 不能激活触发器,因为该操作不记录各个行删除。
十、数据定义语言(DDL)
数据定义语言(DDL)用来定义数据的结构,如创建、修改或者删除数据库对象。常用的数据定义语言有:CREATE , ALTER , DROP 1、CREATE TABLE
语法
CREATE TABLE
[ database_name . [ schema_name ] . | schema_name . ] table_name
( { <column_definition> | <computed_column_definition>
| <column_set_definition> }
[ <table_constraint> ] [ ,...n ] )
[ ON { partition_scheme_name ( partition_column_name ) | filegroup
| "default" } ]
[ { TEXTIMAGE_ON { filegroup | "default" } ]
[ FILESTREAM_ON { partition_scheme_name | filegroup
| "default" } ]
[ WITH ( <table_option> [ ,...n ] ) ]
[ ; ]
<column_definition> ::=
column_name <data_type>
[ FILESTREAM ]
[ COLLATE collation_name ]
[ NULL | NOT NULL ]
[
[ CONSTRAINT constraint_name ] DEFAULT constant_expression ]
| [ IDENTITY [ ( seed ,increment ) ] [ NOT FOR REPLICATION ]
]
[ ROWGUIDCOL ] [ <column_constraint> [ ...n ] ]
[ SPARSE ]
<data type> ::=
[ type_schema_name . ] type_name
[ ( precision [ , scale ] | max |
[ { CONTENT | DOCUMENT } ] xml_schema_collection ) ]
<column_constraint> ::=
[ CONSTRAINT constraint_name ]
{ { PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
[
WITH FILLFACTOR = fillfactor
| WITH ( < index_option > [ , ...n ] )
]
[ ON { partition_scheme_name ( partition_column_name )
| filegroup | "default" } ]
| [ FOREIGN KEY ]
REFERENCES [ schema_name . ] referenced_table_name [ ( ref_column ) ]
[ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
[ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
[ NOT FOR REPLICATION ]
| CHECK [ NOT FOR REPLICATION ] ( logical_expression )
}
<computed_column_definition> ::=
column_name AS computed_column_expression
[ PERSISTED [ NOT NULL ] ]
[
[ CONSTRAINT constraint_name ]
{ PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
[
WITH FILLFACTOR = fillfactor
| WITH ( <index_option> [ , ...n ] )
]
| [ FOREIGN KEY ]
REFERENCES referenced_table_name [ ( ref_column ) ]
[ ON DELETE { NO ACTION | CASCADE } ]
[ ON UPDATE { NO ACTION } ]
[ NOT FOR REPLICATION ]
| CHECK [ NOT FOR REPLICATION ] ( logical_expression )
[ ON { partition_scheme_name ( partition_column_name )
| filegroup | "default" } ]
]
<column_set_definition> ::=
column_set_name XML COLUMN_SET FOR ALL_SPARSE_COLUMNS
< table_constraint > ::=
[ CONSTRAINT constraint_name ]
{
{ PRIMARY KEY | UNIQUE }
[ CLUSTERED | NONCLUSTERED ]
(column [ ASC | DESC ] [ ,...n ] )
[
WITH FILLFACTOR = fillfactor
|WITH ( <index_option> [ , ...n ] )
]
[ ON { partition_scheme_name (partition_column_name)
| filegroup | "default" } ]
| FOREIGN KEY
( column [ ,...n ] )
REFERENCES referenced_table_name [ ( ref_column [ ,...n ] ) ]
[ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
[ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
[ NOT FOR REPLICATION ]
| CHECK [ NOT FOR REPLICATION ] ( logical_expression )
}
<table_option> ::=
{
DATA_COMPRESSION = { NONE | ROW | PAGE }
[ ON PARTITIONS ( { <partition_number_expression> | <range> }
[ , ...n ] ) ]
}
<index_option> ::=
{
PAD_INDEX = { ON | OFF }
| FILLFACTOR = fillfactor
| IGNORE_DUP_KEY = { ON | OFF }
| STATISTICS_NORECOMPUTE = { ON | OFF }
| ALLOW_ROW_LOCKS = { ON | OFF}
| ALLOW_PAGE_LOCKS ={ ON | OFF}
| DATA_COMPRESSION = { NONE | ROW | PAGE }
[ ON PARTITIONS ( { <partition_number_expression> | <range> }
[ , ...n ] ) ]
}
<range> ::=
<partition_number_expression> TO <partition_number_expression>
参数
IDENTITY
指示新列是标识列。在表中添加新行时,数据库引擎将为该列提供一个唯一的增量值。标识列通常与 PRIMARY KEY 约束一起用作表的唯一行标识符。可以将 IDENTITY 属性分配给 tinyint、smallint、int、bigint、decimal(p,0) 或 numeric(p,0) 列。每个表只能创建一个标识列。不能对标识列使用绑定默认值和 DEFAULT 约束。必须同时指定种子和增量,或者两者都不指定。如果二者都未指定,则取默认值 (1,1)。
seed
是装入表的第一行所使用的值。
CONSTRAINT
可选关键字,表示 PRIMARY KEY、NOT NULL、UNIQUE、FOREIGN KEY 或 CHECK 约束定义的开始。 constraint_name
约束的名称。约束名称必须在表所属的架构中唯一。
PRIMARY KEY
是通过唯一索引对给定的一列或多列强制实体完整性的约束。每个表只能创建一个 PRIMARY KEY 约束。
UNIQUE
一个约束,该约束通过唯一索引为一个或多个指定列提供实体完整性。一个表可以有多个 UNIQUE 约束。
CLUSTERED | NONCLUSTERED
指示为 PRIMARY KEY 或 UNIQUE 约束创建聚集索引还是非聚集索引。PRIMARY KEY 约束默认为 CLUSTERED,UNIQUE 约束默认为 NONCLUSTERED。
在 CREATE TABLE 语句中,可只为一个约束指定 CLUSTERED。如果在为 UNIQUE 约束指定 CLUSTERED 的同时又指定了 PRIMARY KEY 约束,则 PRIMARY KEY 将默认为 NONCLUSTERED。
FOREIGN KEY REFERENCES
为列中的数据提供引用完整性的约束。FOREIGN KEY 约束要求列中的每个值在所引用的表中对应的被引用列中都存在。FOREIGN KEY 约束只能引用在所引用的表中是 PRIMARY KEY 或 UNIQUE 约束的列,或所引用的表中在 UNIQUE INDEX 内的被引用列。计算列上的外键也必须标记为 PERSISTED。
ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT }
指定如果已创建表中的行具有引用关系,并且被引用行已从父表中删除,则对这些行采取的操作。默认值为 NO ACTION。
NO ACTION
数据库引擎将引发错误,并回滚对父表中相应行的删除操作。
CASCADE
如果从父表中删除一行,则将从引用表中删除相应行。
SET NULL
如果父表中对应的行被删除,则组成外键的所有值都将设置为 NULL。若要执行此约束,外键列必须可为空值。
SET DEFAULT
如果父表中对应的行被删除,则组成外键的所有值都将设置为默认值。若要执行此约束,所有外键列都必须有默认定义。如果某个列可为空值,并且未设置显式的默认值,则将使用 NULL 作为该列的隐式默认值。
如果该表将包含在使用逻辑记录的合并发布中,则不要指定 CASCADE。有关逻辑记录的详细信息,请参阅通过逻辑记录对相关行的更改进行分组。
如果表中已存在 ON DELETE 的 INSTEAD OF 触发器,则不能定义 ON DELETE 的 CASCADE 操作。 CREATE TABLE 语句完成数据表的定义。典型语法结构如下:
CREATE TABLE table_name (
Field_name data_type [NOT NULL | NULL], [PRIMARY KEY]…)
2、ALTER TABLE
语法 ALTER TABLE [ database_name . [ schema_name ] . | schema_name . ] table_name
{
ALTER COLUMN column_name
{
[ type_schema_name. ] type_name [ ( { precision [ , scale ]
| max | xml_schema_collection } ) ]
[ COLLATE collation_name ]
[ NULL | NOT NULL ]
| {ADD | DROP }
{ ROWGUIDCOL | PERSISTED | NOT FOR REPLICATION | SPARSE }
}
| [ WITH { CHECK | NOCHECK } ]
| ADD
{
<column_definition>
| <computed_column_definition>
| <table_constraint>
| <column_set_definition>
} [ ,...n ]
| DROP
{
[ CONSTRAINT ] constraint_name
[ WITH ( <drop_clustered_constraint_option> [ ,...n ] ) ]
| COLUMN column_name
} [ ,...n ]
| [ WITH { CHECK | NOCHECK } ] { CHECK | NOCHECK } CONSTRAINT
{ ALL | constraint_name [ ,...n ] }
| { ENABLE | DISABLE } TRIGGER
{ ALL | trigger_name [ ,...n ] }
| { ENABLE | DISABLE } CHANGE_TRACKING
[ WITH ( TRACK_COLUMNS_UPDATED = { ON | OFF } ) ]
| SWITCH [ PARTITION source_partition_number_expression ]
TO target_table
[ PARTITION target_partition_number_expression ]
| SET ( FILESTREAM_ON = { partition_scheme_name | filegroup |
"default" | "NULL" } )
| REBUILD
[ [PARTITION = ALL]
[ WITH ( <rebuild_option> [ ,...n ] ) ]
| [ PARTITION = partition_number
[ WITH ( <single_partition_rebuild_option> [ ,...n ] ) ]
]
]
| (<table_option>)
}
[ ; ]
<column_set_definition> ::=
column_set_name XML COLUMN_SET FOR ALL_SPARSE_COLUMNS
<drop_clustered_constraint_option> ::=
{
MAXDOP = max_degree_of_parallelism
| ONLINE = {ON | OFF }
| MOVE TO { partition_scheme_name ( column_name ) | filegroup
| "default" }
}
<table_option> ::=
{
SET ( LOCK_ESCALATION = { AUTO | TABLE | DISABLE } )
}
<single_partition_rebuild__option> ::=
{
SORT_IN_TEMPDB = { ON | OFF }
| MAXDOP = max_degree_of_parallelism
| DATA_COMPRESSION = { NONE | ROW | PAGE} }
}
参数
COLLATE < collation_name >
指定更改后的列的新排序规则。如果未指定,则为该列分配数据库的默认排序规则。排序规则名称既可以是 Windows 排序规则名称,也可以是 SQL 排序规则名称。
COLLATE 子句只能用来更改数据类型为 char、varchar、nchar 和 nvarchar 的列的排序规则。若要更改用户定义别名数据类型列的排序规则,必须执行单独的 ALTER TABLE 语句,将列改为 SQL Server 系统数据类型,并更改其排序规则,然后重新将列改为别名数据类型。
如果出现以下一种或多种情况,则 ALTER COLUMN 不能更改排序规则:
1.CHECK 约束、FOREIGN KEY 约束或计算列引用了更改后的列。
2.已为列创建了索引、统计信息或全文索引。如果更改了列的排序规则,则将删除为更改后的列自动创建的统计信息。
3.架构绑定视图或函数引用了列。
NULL | NOT NULL
指定列是否可接受空值。如果列不允许空值,则只有在指定了默认值或表为空的情况下,才能用 ALTER TABLE 语句添加该列。只有同时指定了 PERSISTED 时,才能为计算列指定 NOT NULL。如果新列允许空值,但没有指定默认值,则新列在表中的每一行都包含一个空值。如果新列允许空值,并且指定了新列的默认值,则可以使用 WITH VALUES 将默认值存储到表中每个现有行的新列中。
如果新列不允许空值,并且表不为空,那么 DEFAULT 定义必须与新列一起添加;并且,加载新列时,每个现有行的新列中将自动包含默认值。
在 ALTER COLUMN 语句中指定 NULL,可以强制 NOT NULL 列允许空值,但 PRIMARY KEY 约束中的列除外。只有列中不包含空值时,才可以在 ALTER COLUMN 中指定 NOT NULL。必须将空值更新为某个值后,才允许执行 ALTER COLUMN NOT NULL 语句
WITH CHECK | WITH NOCHECK
指定表中的数据是否用新添加的或重新启用的 FOREIGN KEY 或 CHECK 约束进行验证。如果未指定,对于新约束,假定为 WITH CHECK,对于重新启用的约束,假定为 WITH NOCHECK。
如果不想根据现有数据验证新的 CHECK 或 FOREIGN KEY 约束,请使用 WITH NOCHECK。除极个别的情况外,建议不要进行这样的操作。在以后所有数据更新中,都将计算该新约束。如果添加约束时用 WITH NOCHECK 禁止了约束冲突,则将来使用不符合该约束的数据来更新行时,可能导致更新失败。
查询优化器不考虑使用 WITH NOCHECK 定义的约束。在使用 ALTER TABLE table CHECK CONSTRAINT ALL 语句重新启用这些约束之前,将忽略这些约束。
ADD
指定添加一个或多个列定义、计算列定义或者表约束。
DROP { [ CONSTRAINT ] constraint_name | COLUMN column_name }
指定从表中删除 constraint_name 或 column_name。可以列出多个列或约束。
可通过查询 sys.check_constraint、sys.default_constraints、sys.key_constraints 和 sys.foreign_keys 目录视图来确定约束的用户定义名称或系统提供的名称。
如果表中存在 XML 索引,则不能删除 PRIMARY KEY 约束。
无法删除以下列:
1.用于索引的列。
2.用于 CHECK、FOREIGN KEY、UNIQUE 或 PRIMARY KEY 约束的列。
3.与默认值(由 DEFAULT 关键字定义)相关联的列,或绑定到默认对象的列。
4.绑定到规则的列。
ALTER TABLE语句可以完成对现有表的修改。可以更改、添加、除去列和约束,或者启用和禁用约束和触发器。典型语法结构如下
ALTER TABLE table_name
ADD COLUMN field_name datatype
通常表的结构可以用Create table一次创建,但是当发现表的定义不符合要求或者要求建立新的约束的时候,可以用ALTER TABLE 来调整表结构。
3、DROP table
DROP TABLE语句完成从数据库中删除表的操作。同时删除该表的所有数据、索引、触发器、约束和权限规范。典型语法结构如下:
DROP TABLE table_name
DROP TABLE语句不能用于除去由FOREIGN KEY约束引用的表。必须先除去引用的FOREIGN KEY约束或引用的表。除去表时,表上的规则或默认值将解除绑定,任何与表关联的约束和触发器将自动除去。如果重新创建表,必须重新绑定适当的规则和默认值,重新创建任何触发器并添加必要的约束。如果使用 DELETE tablename 删除表中的所有行或使用 TRUNCATE TABLE 语句,则在被移除之前,表将一直存在。
删除使用了超过 128 个区的大型表和索引时,需要分两个单独的阶段:逻辑和物理阶段。在逻辑阶段中,对表使用的现有分配单元进行标记以便释放,并对其进行锁定,直到事务提交为止。在物理阶段,标记为要释放的 IAM 页被成批地物理删除。
在删除表之前,可以用系统存储过程sp_depends检查依存关系,显示有关数据库对象相关性的信息,格式为:sp_depends tablename
在系统表中不能使用DROP TABLE语句
例如:从当前数据库中删除student表及其数据和索引
DROP TABLE student
十一、子查询
子查询是一个嵌套在 SELECT、INSERT、UPDATE 或 DELETE 语句或其他子查询中的查询。任何允许使用表达式的地方都可以使用子查询。
子查询也称为内部查询或内部选择,而包含子查询的语句也称为外部查询或外部选择。 许多包含子查询的 Transact-SQL 语句都可以改用联接表示。其他问题只能通过子查询提出。在 Transact-SQL 中,包含子查询的语句和语义上等效的不包含子查询的语句在性能上通常没有差别。但是,在一些必须检查存在性的情况中,使用联接会产生更好的性能。否则,为确保消除重复值,必须为外部查询的每个结果都处理嵌套查询。所以在这些情况下,联接方式会产生更好的效果。
嵌套在外部 SELECT 语句中的子查询包括以下组件:
1.包含常规选择列表组件的常规 SELECT 查询。
2.包含一个或多个表或视图名称的常规 FROM 子句。
3.可选的 WHERE 子句。
4.可选的 GROUP BY 子句。
5.可选的 HAVING 子句。
子查询的 SELECT 查询总是使用圆括号括起来。它不能包含 COMPUTE 或 FOR BROWSE 子句,如果同时指定了 TOP 子句,则只能包含 ORDER BY 子句。
子查询可以嵌套在外部 SELECT、INSERT、UPDATE 或 DELETE 语句的 WHERE 或 HAVING 子句内,也可以嵌套在其他子查询内。尽管根据可用内存和查询中其他表达式的复杂程度的不同,嵌套限制也有所不同,但嵌套到 32 层是可能的。个别查询可能不支持 32 层嵌套。任何可以使用表达式的地方都可以使用子查询,只要它返回的是单个值。
如果某个表只出现在子查询中,而没有出现在外部查询中,那么该表中的列就无法包含在输出(外部查询的选择列表)中。
包含子查询的语句通常采用以下格式中的一种:
1.WHERE expression [NOT] IN (subquery)
2.WHERE expression comparison_operator [ANY | ALL] (subquery)
3.WHERE [NOT] EXISTS (subquery)
有三种基本的子查询。它们是:
1.在通过 IN 或由 ANY 或 ALL 修改的比较运算符引入的列表上操作。
2.通过未修改的比较运算符引入且必须返回单个值。
3.通过 EXISTS 引入的存在测试。
用 ANY、SOME 或 ALL 修改的比较运算符
可以用 ALL 或 ANY 关键字修改引入子查询的比较运算符。SOME 是与 ANY 等效的 ISO 标准。通过修改的比较运算符引入的子查询返回零个值或多个值的列表,并且可以包括 GROUP BY 或 HAVING 子句。这些子查询可以用 EXISTS 重新表述。
以 > 比较运算符为例,>ALL 表示大于每一个值。换句话说,它表示大于最大值。例如,>ALL (1, 2, 3) 表示大于 3。>ANY 表示至少大于一个值,即大于最小值。因此 >ANY (1, 2,
3) 表示大于 1。若要使带有 >ALL 的子查询中的行满足外部查询中指定的条件,引入子查询的列中的值必须大于子查询返回的值列表中的每个值。同样,>ANY 表示要使某一行满足外部查询中指定的条件,引入子查询的列中的值必须至少大于子查询返回的值列表中的一个值。
使用 EXISTS 的子查询
使用 EXISTS 关键字引入子查询后,子查询的作用就相当于进行存在测试。外部查询的 WHERE 子句测试子查询返回的行是否存在。子查询实际上不产生任何数据,它只返回 TRUE
或 FALSE 值。
使用 EXISTS 引入的子查询的语法如下:
WHERE [NOT] EXISTS (subquery)
注意,使用 EXISTS 引入的子查询在下列方面与其他子查询略有不同:
1.EXISTS 关键字前面没有列名、常量或其他表达式。
2.由 EXISTS 引入的子查询的选择列表通常几乎都是由星号 (*) 组成。由于只是测试是否存在符合子查询中指定条件的行,因此不必列出列名。
3.由于通常没有备选的、非子查询的表示法,因此 EXISTS 关键字很重要。尽管一些使用 EXISTS 创建的查询不能以任何其他方法表示,但许多查询都可以使用 IN 或者由 ANY 或 ALL 修改的比较运算符来获取类似结果。
子查询本身收到以下条件的限制:
1、通过比较运算符引入的子查询的选择列表只能包括一个表达式或列名称(分别对SELECT * 或列表尽兴EXISTS和IN操作除外)
2、如果外部查询的WHERE子句包括某个列名,则该子句必须与子查询的选择列表中的该列在连接上兼容
3、子查询的选择列中不允许出现ntext,text,image数据类型
4、由于必须返回单个值,所以由无修改的比较运算符(指其后未接关键字ANY或ALL)引入的子查询不能包括GROUP BY 和HAVING子句。
5、包括GROUP BY的子查询不能使用DISTINCT关键字
6、不能指定COMPUTE和INTO 子句。
7、只有同时指定了TOP,才可以指定ORDER BY
8、按约定,通过EXISTS引入的子查询的选择列表由(*)组成,而不使用单个列名。由于通过EXISTS引入的子查询进行了存在测试,并返回TRUE或FALSE而非数据,所以这些子查询的规则与标准选择列表的规则完全相同。
备注:如果不是特别的需要,尽量不要使用子查询,因为子查询不如用连接执行的效率高,一般的子查询语句都可以用连接代替。
十二、联合查询
查询结果可以来自多个表,使用UNION可以实现查询结果的合并。也可以用连接实现从多个表中返回数据。连接分为内连接,外连接和交叉连接。内连接(INNER JION)使用比较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN)和全外连接(FULL OUTER JOIN 或FULL JOIN)三种。交叉连接(CROSS JOIN)没有WHERE子句,它返回列表中所有数据行的笛卡尔积。
若要把多个SELECT语句的结果合并为一个结果,可用UNION操作来完成,使用UNION将多个查询结果合并起来,形成一个完整的查询结果时,系统会自动去掉重复的记录。
注意:参加UNION操作的各数据项数目必须相同;对应项的数据类型也必须相同。 ALL关键字与UNION一起使用,作为它的一个可选参数,使用了ALL关键字以后,在查询结果中将包含所有的行(包括重复行),默认的情况是不用ALL,删除重复行
JOIN
指示指定的联接操作应在指定的表源或视图之间执行。
ON <search_condition>
指定联接所基于的条件。尽管常常使用列运算符和比较运算符,但此条件可指定任何谓词,例如:
select sname,cname,cteacher
from student as s
join sc on s.sno=sc.sno
join course as c
on sc.cno=c.cno
当条件指定列时,列不一定必须具有相同的名称或数据类型;但是,如果数据类型不相同,则这些列要么必须相互兼容,要么是 SQL Server 能够隐性转换的类型。如果数据类型不能隐式转换,则在条件中必须使用 CONVERT 函数显式转换数据类型。
内连接INNER JOIN 是SQL Server 中默认的连接类型,返回两个表中相匹配的记录,而相连接的两个表中不匹配的记录则不显示。在一个JOIN语句中可以链接多个ON子句。
链接的过程是先从相连接的表中生成笛卡尔积,然后根据指定的条件进行筛选。
注意:在一个INNER JOIN之中,可以嵌套LEFT JOIN 或RIGHT JOIN,但是在LEFT JOIN 或RIGHT JOIN中不能选择嵌套INNER JOIN。
相对于内连接,LEFT JOIN 和 RIGHT JOIN都属于外连接,使用LEFT JOIN来创建一个左边外部外连接。左边外部连接将包含了第一个(左边)开始的两个表中的全部记录,即使在第二个表中并没有相符值的记录。使用RIGHT JOIN来创建一个右边外部外连接。右边外部连接将包含了第二个(右边)开始的两个表中的全部记录,即使在第一个(左边)表中并没有相符值的记录。
通过使用交叉连接(CROSS JOIN),可以返回两个表的笛卡尔积,就像使用了INNER JOIN而没有指定WHERE子句一样。CROSS JOIN 是简单地,不加任何约束条件的吧表组合。CROSS JOIN后结果的行数是连接前两个表行数的乘积。如果对两个分别有好几千行的表进行连接,那么结果行数将是巨大的。
十三、查询优化
1、用于对运行慢的查询进行分析的清单
引起查询或更新的执行时间超过预期时间的原因有多种。查询运行慢,可能是由与运行 SQL Server 的网络或计算机相关的性能问题引起的,也可能是由物理数据库设计问题引起的。查询和更新运行慢的常见原因有多种:
1.网络通讯速度慢。
2.服务器的内存不足,或者没有足够的内存供 SQL Server 使用。
3.索引列上缺少有用的统计信息。
4.索引列上的统计信息过期。
5.缺少有用的索引。
6.缺少有用的索引视图。
7.缺少有用的数据条带化。
8.缺少有用的分区。
当查询或更新花费的时间比预期时间长时,请考虑以下问题,找到可解答前一节中列出的查询运行慢的原因:
1.是与组件而不是与查询相关的性能问题吗?例如,是网络性能低的问题吗?有其他可能引起或造成性能降低的组件吗?Windows 系统监视器可用于监视与 SQL Server 和非 SQL Server 相关的组件的性能。
2.如果性能问题与查询相关,那么涉及到的是哪个或哪组查询?使用 SQL Server Profiler 帮助识别速度缓慢的查询。使用 sys.dm_exec_query_stats 和 sys.dm_exec_requests 动态管理视图查找共同消耗大量资源的类似查询。
3.如何分析运行慢的查询的性能?标识了运行慢的一个或多个查询之后,可以通过生成显示计划来进一步分析查询性能,该显示计划可以是查询优化器生成的文本、XML 或查询执
行计划的图形表示形式。您可以使用 Transact-SQL SET 选项、SQL Server Management Studio 或 SQL Server Profiler 来生成显示计划。由这些工具收集的信息使您能够确定 SQL Server 查询优化器如何执行查询以及使用的是哪些索引。利用这些信息,可以确定通过重写查询、更改表上的索引或修改数据库设计等方法能否提高性能。
4.是否已经用有用的统计信息优化查询?SQL Server 自动在索引列上创建对列内值的分布情况的统计信息。也可以手动(使用 SQL Server Management Studio 或 CREATE STATISTICS 语句)或自动(如果将 AUTO_CREATE_STATISTICS 数据库选项设置为 TRUE)在非索引列上创建这些统计信息。查询处理器可以利用这些统计信息来确定最佳的查询评估策略。在联接操作所涉及的非索引列上维护附加的统计信息可以提高查询性能。使用 SQL Server Profiler 或 SQL Server Management Studio 内的图形执行计划来监视查询,以确定查询是否有足够的统计信息。
5.查询统计是最新的吗?统计信息是自动更新的吗?SQL Server 自动在索引列上创建并更新查询统计信息(只要没有禁用对查询统计信息的自动更新)。另外,也可以手动(使用 SQL Server Management Studio 或 UPDATE STATISTICS 语句)或自动(如果将 AUTO_UPDATE_STATISTICS 数据库选项设置为 TRUE)在非索引列上更新统计信息。最新的统计信息不取决于日期或时间数据。如果尚未执行 UPDATE 操作,则查询统计信息仍是最新的。如果没有将统计信息设置为自动更新,请进行设置。
6.有合适的索引吗?添加一个或多个索引会不会提高查询性能?数据库引擎优化顾问也可能建议创建必要的统计信息。
7.有数据热点或索引热点吗?请考虑使用磁盘条带化。使用 0 级 RAID(独立磁盘冗余阵列)可实现磁盘条带化,在这种 RAID 上,数据分布在多个磁盘驱动器上。
8.是否为查询优化器提供了优化复杂查询的最有利条件?
9.如果数据量很大,需要将其分区吗?便于数据管理是分区的主要优点,而如果将数据的表和索引进行相似的分区,则分区还可以提高查询性能。