数据库是为更方便有效地管理信息而存在的人们,希望数据库可以随时提供所需要的数据信息。因此,对用户来说,数据查询是数据
库最重要的功能。本章将讲述数据查询的实现方法。
在数据库中,数据查询是通过SELECT 语句来完成的。SELECT 语句可以从数据库中 按用户要求检索数据,并将查询结果以表格的形式返回。我们在“Transact-SQL 语言”章 节及前面的章节中已经初步接触到了SELECT 语句的一些用法,在本章中将分类讲述其 具体用法。
本节讲述SELECT 语句完整的语法结构,这是一个非常冗长、枯燥的过程。读者可 以跳过本节,从第二节开始阅读,而将本节作为理解、编写查询语句的语法参考资料。 SELECT 语句完整的语法结构如下:
SELECT statement ::=
1<query_expression>
2[ ORDER BY { order_by_expression | column_position [ ASC | DESC ] } [,...n] ]
3[ COMPUTE { { AVG | COUNT | MAX | MIN | SUM } (expression) } [,...n]
4[ BY expression [,...n] ] ]
5[ FOR { BROWSE | XML { RAW | AUTO | EXPLICIT }
6[ , XMLDATA ]
7[ , ELEMENTS ]
8[ , BINARY base64 ] }
9[ OPTION (<query_hint> [,...n]) ]
10<query expression=""> ::=
11{ <query specification=""> | (<query expression="">) }
12[UNION [ALL] <query (<query="" expression="" specification="" |="">) [...n] ]
13<query specification=""> ::=
14SELECT [ ALL | DISTINCT ]
15[ {TOP integer | TOP integer PERCENT} [ WITH TIES] ]
16<select_list>
17[ INTO new_table ]
18[ FROM {<table_source>} [,...n] ]
19[ WHERE <search_condition> ]
20[ GROUP BY [ALL] group_by_expression [,...n]
21[ WITH { CUBE | ROLLUP } ] ]
22[ HAVING <search_condition> ]
23由于SELECT 语句特别复杂,上述结构还不能完全说明其用法,因此我们将它拆分为若干部分来讲述。
24
2510.1.1 SELECT 子句
26SELECT 子句指定需要通过查询返回的表的列,其语法如下:
27SELECT [ ALL | DISTINCT ]
28[ TOP n [PERCENT] [ WITH TIES] ]
29<select_list>
30<select_list> ::=
31{ *
32| { table_name | view_name | table_alias }.*
33| { column_name | expression | IDENTITYCOL | ROWGUIDCOL }
34[ [AS] column_alias ]
35| column_alias = expression
36} [,...n]
37各参数说明如下:
38
39 * ALL
40指明查询结果中可以显示值相同的列。ALL 是系统默认的。
41 * DISTINCT
42指明查询结果中如果有值相同的列,则只显示其中的一列。对DISTINCT 选项来说, Null 值被认为是相同的值。
43 * TOP n [PERCENT]
44指定返回查询结果的前n 行数据。如果PERCENT 关键字指定的话,则返回查询结果 的前百分之n 行数据。
45 * WITH TIES
46此选项只能在使用了ORDER BY 子句后才能使用当指定此项时,除了返回由TOP n (PERCENT) 指定的数据行外,还要返回与TOP n (PERCENT) 返回的最后一行记录中 由ORDER BY 子句指定的列的列值相同的数据行。
47 * select_list
48select_list 是所要查询的表的列的集合,多个列之间用逗号分开。
49 * * 通配符,返回所有对象的所有列。
50
51 * table_name | view_name | table_alias.*
52限制通配符*的作用范围。凡是带*的项,均返回其中所有的列。
53 * column_name
54指定返回的列名
55 * expression
56表达式可以为列名、常量、函数或它们的组合。
57 * IDENTITYCOL
58返回IDENTITY 列。如果FROM 子句中有多个表含有IDENTITY 列,则在IDENTTYCOL 选项前必须加上表名,如Table1.IDENTITYCOL。
59 * ROWGUIDCOL
60返回表的ROWGUIDCOL 列。同IDENTITYCOL 选项相同,当要指定多个ROWGUIDCOL 列时,选项前必须加上表名,如Table1. ROWGUIDCOL。
61 * column_alias
62在返回的查询结果中用此别名替代列的原名。column_alias 可用于ORDER BY 子句, 但不能用于WHERE GROUP BY 或HAVING 子句如果查询是游标声明命令DECLARE CURSOR 的一部分,则column_alias 还不能用于FOR UPDATE 子句(有关游标的介绍请 参见“游标和视图”章节)。
63
64
65
6610.1.2 INTO 子句
67INTO 子句用于把查询结果存放到一个新建的表中。SELECT...INTO 句式不能与COMPUTE 子句一起使用。其语法如下:
68INTO new_table
69参数new_table 指定了新建的表的名称。新表的列由SELECT 子句中指定的列构成,新表中的数据行是由WHERE 子句指定的。但如果SELECT 子句中指定了计算列,在新表中对应的列则不是计算列,而是一个实际存储在表中的列,其中的数据由执行SELECT...INTO 语句时计算得出。如果数据库的“Select into/bulk copy” 选项设置为“True/On”,则可以用INTO 子句创建表和临时表,反之,则只能创建临时表。
70
7110.1.3 FROM 子句
72FROM 子句指定需要进行数据查询的表。只要SELECT 子句中有要查询的列,就必须使用FROM 子句。其语法如下:
73FROM {<table_source>} [,...n]
74<table_source> ::=
75table_name [ [AS] table_alias ] [ WITH ( <table_hint> [,...n]) ]
76| view_name [ [AS] table_alias ]
77| rowset_function [ [AS] table_alias ]
78| OPENXML
79| derived_table [AS] table_alias [ (column_alias [,...n] ) ]
80| <joined_table>
81<joined_table> ::=
82<table_source> <join_type> <table_source> ON <search_condition>
83| <table_source> CROSS JOIN <table_source>
84| <joined_table>
85<join_type> ::=
86[ INNER | { { LEFT | RIGHT | FULL } [OUTER] } ]
87[ <join_hint> ]
88JOIN
89各参数说明如下:
90
91 * table_source
92指明SELECT 语句要用到的表、视图等数据源。
93 * table_name [ [AS] table_alias ]
94指明表名和表的别名。
95 * view_name [ [AS] table_alias ]
96指明视图名称和视图的别名。
97 * rowset_function [ [AS] table_alias ]
98指明行统计函数和统计列的名称。
99 * OPENXML
100提供一个XML 文档的行集合视图。
101 * WITH ( [,...n])
102指定一个或多个表提示。通常SQL Server 的查询优化器会自动选取最优执行计划, 除非是特别有经验的用户,否则最好不用此选项。关于表提示table_hint 的设,定请参见 下一章的“删除数据”部分。
103 * derived_table [AS] table_alias
104指定一个子查询,从数据库中返回数据行。
105 * column_alias
106指明列的别名,用以替换查询结果中的列名。
107 * joined_table
108指定由连接查询生成的查询结果。有关连接与连接查询的介绍参见本章的相关章节。
109 * join_type
110指定连接查询操作的类型。
111 * INNER
112指定返回两个表中所有匹配的行。如果没有join_type 选项,此选项就为系统默认。
113 * LEFT [OUTER]
114返回连接查询左边的表中所有的相应记录,而右表中对应于左表无记录的部分,用NULL 值表示。
115 * RIGHT [OUTER]
116返回连接查询右边的表中所有的相应记录,而左表中对应于右表无记录的部分,用NULL 值表示。
117 * FULL [OUTER]
118返回连接的两个表中的所有记录。无对应记录的部分用NULL 值表示。
119 * join_hint
120指定一个连接提示或运算法则。如果指定了此选项,则INNER LEFT RIGHT 或FULL选项必须明确指定。通常SQL Server 的查询优化器会自动选取最优执行计划,除非是特别有经验的用户,否则最好不用此选项。
121join_hint 的语法如下:
122<join_hint> ::= { LOOP | HASH | MERGE | REMOTE }
123其中LOOP | HASH | MERGE 选项指定查询优化器中的连接是循环、散列或合并的。REMOTE 选项指定连接操作由右边的表完成。当左表的数据行少于右表,才能使用REMOTE 选项。当左表和右表都是本地表时,此选项不必使用。
124 * JOIN
125指明特定的表或视图将要被连接。
126 * ON <search_condition>
127指定连接的条件。
128 * CROSS JOIN
129返回两个表交叉查询的结果。
130
13110.1.4 WHERE 子句
132WHERE 子句指定数据检索的条件,以限制返回的数据行。其语法如下:
133WHERE <search_condition> | <old_outer_join>
134<old_outer_join> ::=
135column_name { *= | =* } column_name
136各参数说明如下:
137search_condition
138通过由谓词构成的条件来限制返回的查询结果。
139old_outer_join
140指定一个外连接。此选项是不标准的,但使用方便。它用“*=” 操作符表示左连接,用“=*” 操作符表示右连接。此选项与在FROM 子句中指定外连接都是可行的方法,但二者只能择其一。
141
142**注意:** 如果在WHERE子句中指定一个值为FALSE的条件,则可以用SELECT...INTO语句来创建一个表名不同,但结构和数据类型均和原表相同的表。
143
14410.1.5 GROUP BY 子句
145GROUP BY 子句指定查询结果的分组条件。其语法如下;
146GROUP BY [ALL] group_by_expression [,...n]
147[ WITH { CUBE | ROLLUP } ]
148各参数说明如下:
149
150
151 * ALL
152返回所有可能的查询结果组合,即使此组合中没有任何满足WHERE 子句的数据。分组的统计列如果不满足查询条件,则将由NULL 值构成其数据。ALL 选项不能与CUBE或ROLLUP 选项同时使用。
153GROUP BY ALL is not supported in queries that access remote tables.
154 * group_by_expression
155指明分组条件。group_by_expression 通常是一个列名,但不能是列的别名。数据类型为TEXT、 NTEXT、 IMAGE 或BIT 类型的列不能作为分组条件。
156 * CUBE
157除了返回由GROUP BY 子句指定的列外,还返回按组统计的行。返回的结果先按分组的第一个条件列排序显示,再按第二个条件列排序显示以此类推。统计行包括了GROUPBY 子句指定的列的各种组合的数据统计。
158 * ROLLUP
159与CUBE 不同的是,此选项对GROUP BY 子句中的列顺序敏感,它只返回第一个分 组条件指定的列的统计行。改变列的顺序会使返回的结果的行数发生变化。
160
161
162
163使用Distinct选项的统计函数,如AVG(DISTINCT column_name)、COUNT(DISTINCT column_name)、和SUM(DISTINCT column_name)等,不能在使用CUBE或ROLLUP选项时使用。
164
16510.1.6 HAVING 子句
166HAVING 子句指定分组搜索条件。HAVING 子句通常与GROUP BY 子句一起使用。TEXT、 NTEXT 和IMAGE 数据类型不能用于HAVING 子句。其语法如下:
167HAVING <search_condition>
168HAVING 子句与WHERE 子句很相似,其区别在于其作用的对象不同。WHERE 子句作用于表和视图,HAVING 子句作用于组。
169
17010.1.7 UNION 操作符
171UNION 操作符将两个或两个以上的查询结果合并为一个结果集。它与使用连接查询合并两个表的列是不同的。使用UNION 操作符合并查询结果需要遵循两个基本规则:
172
173 * 列的数目和顺序在所有查询中必须是一致的;
174 * 数据类型必须兼容。
175其语法如下:
176<query specification=""> | (<query expression="">)
177UNION [ALL]
178<query (<query="" expression="" specification="" |="">)
179[UNION [ALL] <query (<query="" expression="" specification="" |="">) [...n] ]
180各参数说明如下:
181 * <query_specification> | (<query_expression>)
182指明查询的详细说明或查询表达式。
183 * UNION
184合并操作符。
185 * ALL
186合并所有数据行到结果中,包括值重复的数据行。如果不指定此选项,则重复的数据行只显示一行。
187
188
189
19010.1.8 ORDER BY 子句
191ORDER BY 子句指定查询结果的排序方式。其语法如下:
192ORDER BY {order_by_expression [ ASC | DESC ] } [,...n]
193各参数说明如下:
194
195 * order_by_expression
196指定排序的规则。order_by_expression 可以是表或视图的列的名称或别名。如果SELECT 语句中没有使用DISTINCT 选项或UNION 操作符。那么ORDER BY 子句中可以包 含select list 中没有出现的列名。或别名ORDER BY 子句中也不能使用TEXT、 NTEXT 和 IMAGE 数据类型。
197 * ASC
198指明查询结果按升序排列。这是系统默认值。
199 * DESC
200指明查询结果按降序排列。
201**注意:** Null值被作为最小的值。
202
203
204
20510.1.9 COMPUTE 子句
206COMPUTE 子句在查询结果的末尾生成一个汇总数据行。其语法如下:
207COMPUTE
208{ { AVG | COUNT | MAX | MIN | STDEV | STDEVP |VAR | VARP | SUM }
209(expression) } [,...n]
210[ BY expression [,...n] ]
211各参数说明如下:
212AVG | COUNT | MAX | MIN | STDEV | STDEVP | VAR | VARP | SUM()以上参数与对应的函数有相同的含义。这些函数均会忽略NULL 值,且DISTINCT选项不能在此使用。
213expression
214指定需要统计的列的名称。此列必须包含于SELECT 列表中,且不能用别名。COMPUTE子句中也不能使用TEXT、 NTEXT 和IMAGE 数据类型。
215BY expression
216在查询结果中生成分类统计的行。如果使用此选,项则必须同时使用ORDER BY 子句。expression 是对应的ORDER BY 子句中的order_by_expression 的子集或全集。
217**注意:** 在SELECT子句中使用统计函数,会覆盖COMPUTE子句中的相应选项。在SELECTINTO语句中不能使用COMPUTE子句。
218
21910.1.10 FOR BROWSE 子句
220FOR BROWSE 子句用于读取另外的用户正在进行添加、删除或更新记录的表。其语法如下:
221FOR { BROWSE | XML { RAW | AUTO | EXPLICIT }
222[ , XMLDATA ]
223[ , ELEMENTS ]
224[ , BINARY base64 ]
225}
226各参数说明如下:
227BROWSE
228BROWSE 选项指明当查看在使用DB-Library 的客户机应用程序中的数据时,可以更新数据。
229使用此子句时对所操作的表有一些限制:
230表必须包含一个timestamp 类型的时间标识列;
231表必须有一个惟一索引。
232**注意:**
233在SELECT语句中:FOR BROWSE子句必须是SELECT语句的最后子句;FOR BROWSE子句不能与UNION操作符同时使用;FOR BROWSE子句不能与表提示HOLDLOCK选项同时使用。
234
235 * XML
236XML 选项指明查询结果以XML 文档模式返回XML。 模式分为RAW、 AUTO、 EXPLICIT 三种。
237 * RAW
238将查询结果每一行转换为以一个普通标识符 作为元素标识XML 文档。
239 * AUTO
240以简单嵌套的XML 树方式返回查询结果。
241 * EXPLICIT
242指定查询结果的XML 树的形式被明确定义的。
243 * XMLDATA
244返回概要信息。它是附加在文档上返回的。
245 * ELEMENTS
246指明列将以子元素的方式返回。
247 * BINARY base 64
248指定查询返回的以base64 格式编码的二进制数据。
249 * 10.1.11 OPTION 子句
250OPTION 子句用于指定在整个查询过程中的查询提示(Query Hint)。通常,用户不 必使用OPTION 子句,因为查询优化器会自动选择一个最佳的查询计划。OPTION 子句 必须由最外层的主查询来指定。各查询提示之间应使用逗号隔开。其语法如下:
251OPTION (<query_hint> [,...n] )
252<query_hint> ::=
253{ { HASH | ORDER } GROUP
254| { CONCAT | HASH | MERGE } UNION
255| { LOOP | MERGE | HASH } JOIN
256| FAST number_rows
257| FORCE ORDER
258| MAXDOP number
259| ROBUST PLAN
260| KEEP PLAN
261| KEEPFIXED PLAN
262| EXPAND VIEWS
263}
264各参数说明如下:
265 * {HASH | ORDER} GROUP
266指定在GROUP BY 或COMPUTE 子句中指定的查询使用散列法或排序法。所谓散列法是指为存储和检索数据项或数据,把搜索关键字转换为一个地址的一种方法。该方法常作为数据集内的记录的一种算法,可以使记录分组均匀,减少搜索时间。
267 * {MERGE | HASH | CONCAT} UNION
268指定所有的UNION 操作符采用合并(Merge)、散列(Hash) 或连接(Concatenate)的方法执行操作。如果指定了多个UNION 提示,查询优化器会挑选一个最佳的提示方案。
269 * {LOOP | MERGE | HASH |} JOIN
270指定查询过程中的所有连接操作采取循环连接(Loop Join)、合并连接(Merge Join)或散列连接(Hash Join) 的方法。如果指定了多个JOIN 提示,查询优化器会挑选一个最佳的提示方案。
271 * FAST number_rows
272指定查询优化只用于迅速返回前number_rows 行数据,在number_rows 行以后的数据采用原查询方法。
273 * FORCE ORDER
274指定在查询语法中说明的连接顺序在查询优化的过程中保持不变。
275 * MAXDOP number
276忽略由Sp_configure 设定的针对查询的最大并行线程数目。
277 * ROBUST PLAN
278强制查询优化器尝试使用最大行容量的计划。
279 * KEEP PLAN
280强制查询优化器放松重新编译查询的阈值。指定此选项可以让一个表被多次更新而不必频繁地重新编译查询。
281 * KEEPFIXED PLAN
282强制查询优化器不重新编译查询。这样只有当表的概要改变或执行Sp_recompile 存储过程时,才会重新编译查询。
283 * EXPAND VIEWS
284扩展索引化视图(当一个视图的名称在查询文本中被视图定义替换时称这个视图被扩展了),并且查询优化器不再将索引化视图作为查询的某部分的替代品。如果视图使用了WITH (NOEXPAND) 说明,则不能被扩展。
285
286**注意:** SELECT语句中各子句的排列次序是很重要的,子句必须依相应的次序来使用。
287当用SELECT命令读取TEXT和IMAGE类型数据时,一次所能读取的数据受限于@@TE-XTSIZE全局变量的值。
288可以用SET TEXTSIZE命令来更改它。@@TEXTSIZE的初始值为4K,最大为231-1(2,147,483,647)个字节。</query_hint></query_hint></query_expression></query_specification></query></query></query></query></search_condition></old_outer_join></old_outer_join></search_condition></search_condition></join_hint></join_hint></join_type></joined_table></table_source></table_source></search_condition></table_source></join_type></table_source></joined_table></joined_table></table_hint></table_source></table_source></select_list></select_list></search_condition></search_condition></table_source></select_list></query></query></query></query></query></query_hint></query_expression>