一、简单查询 $  Lfbt=f  
 g*FHZM*N9  
简单的Transact-SQL查询只包括选择列表、FROM子句和WHERE子句。它们分别说明所查询列、查询的 uAnL`  
 U:7w8$_  
表或视图、以及搜索条件等。 k
t!@}QP  
 =os!^{p7>  
例如,下面的语句查询testtable表中姓名为“张三”的nickname字段和email字段。 xv147"w'v  
 QhTn9S:D  
SELECT nickname,email 4IOqSB|  
 jT0iJ?d,!  
FROM testtable  y"Fu=  
 DU,B  
WHERE name='张三' hJ%$Te  
 lBG=jOS  
(一)选择列表 v h)CB8  
 h*<`ct xL  
选择列表(select_list)指出所查询列,它可以是一组列名列表、星号、表达式、变量(包括局部变 ->{\7|^  
 5G2ueRVb  
量和全局变量)等构成。 v;z8g^L  
 LdiNXyyzet  
1、选择所有列 
>_]Ov:5  
 s+	*LVfau  
例如,下面语句显示testtable表中所有列的数据: ;mD!8<~z.  
 \N|}V.r  
SELECT * vnbY^ASdw  
 8 *m,#	  
FROM testtable )iIsnM  
 |Om][z  
2、选择部分列并指定它们的显示次序 B&KIM{j\  
 vP'!&}  
查询结果集合中数据的排列顺序与选择列表中所指定的列名排列顺序相同。 beYGP  
 Ssir?ZUm   
例如: e
:ub]1I=  
 5xUZeLj  
SELECT nickname,email \(^]R,~*!b  
 ebL0cK?  
FROM testtable c?c"|.-<p  
 7?_gm>]a  
3、更改列标题 fK(:vwh  
 v'`qn  
在选择列表中,可重新指定列标题。定义格式为: 	 B\=T_'E&  
 (yEU9R$I"  
列标题=列名 .}!.:
|  
 cZ`%Gt6g  
列名 列标题 ?)Gb=   
 cF9ZnT.  
如果指定的列标题不是标准的标识符格式时,应使用引号定界符,例如,下列语句使用汉字显示列 .hf%L1N%F  
 "f3mi[  
标题: BdvpG  
 ]5j>O^c<  
SELECT 昵称=nickname,电子邮件=email ;u';$0  
 C^]UK  
FROM testtable wB[
JFy"E  
 X`E}2|q'  
4、删除重复行 F2n4#b  
 V^;lg[:  
SELECT语句中使用ALL或DISTINCT选项来显示表中符合条件的所有行或删除其中重复的数据行,默认 Y!(w. G  
 7<8'7<X  
为ALL。使用DISTINCT选项时,对于所有重复的数据行在SELECT返回的结果集合中只保留一行。 1]8Hpd  
 3s*mq@~1X  
5、限制返回的行数 >*l2]3'`  
 G%jV}7h  
使用TOP n [PERCENT]选项限制返回的数据行数,TOP n说明返回n行,而TOP n PERCENT时,说明n是 >N~jlr |  
 ja{x}n*5  
表示一百分数,指定返回的行数等于总行数的百分之几。 H\<PGC"_Y  
 5ry[Lgg  
例如: -=u9>S)!c  
 
n:<Xp[;R  
SELECT TOP 2 * 9(a*0H  
 S@,x^/vT  
FROM testtable O15~\8#'  
 [[4!b E  
SELECT TOP 20 PERCENT * 
hJ8B&u(  
 sv\=/F@n  
FROM testtable q.ppYXJUXi  
 K_X(j$2Xc  
(二)FROM子句 p+2%LYR u  
 =k!F`H`/%'  
FROM子句指定SELECT语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图, BMU#pK;P]  
 TPZ^hL>ao  
它们之间用逗号分隔。 #g
Rns  
 |Y+[_D}  
在FROM子句同时指定多个表或视图时,如果选择列表中存在同名列,这时应使用对象名限定这些列 *unJd"<*&@  
 dTU`@!f  
所属的表或视图。例如在usertable和citytable表中同时存在cityid列,在查询两个表中的cityid时应 Ao9|t;i  
 >	3l3  
使用下面语句格式加以限定: gF~
}  
 cgQ2Wo7tCq  
SELECT username,citytable.cityid |'L$ogt6  
 $A: ?o?"7}  
FROM usertable,citytable 5XNFu	C9E  
 o-AAx#@  
WHERE usertable.cityid=citytable.cityid {~=gKZ:-@  
 O;#0Yg  
在FROM子句中可用以下两种格式为表或视图指定别名: t$uj( y>  
 !8J%%Ux&M  
表名 as 别名 [lj^lN8  
 C9`x"$  
表名 别名 YQ}IE[J}v  
 +|O&k  
例如上面语句可用表的别名格式表示为: -s:NF;"  
 7(zY:9|(  
SELECT username,b.cityid O~F8lQ  
 VZU@G)rd  
FROM usertable a,citytable b k/%n7 ;1  
 f{R/rb&iB  
WHERE a.cityid=b.cityid EMS$?"K  
 S#Pni}JD  
SELECT不仅能从表或视图中检索数据,它还能够从其它查询语句所返回的结果集合中查询数据。 [PU0!W;  
 )G$0:-J-  
例如: #xxs^Kbqa#  
 n{.SNipU  
SELECT a.au_fname+a.au_lname .\AbE*lZ#  
 h&t9CpTfeJ  
FROM authors a,titleauthor ta WcE/,<^*  
 )u5+<OG}=  
(SELECT title_id,title j1P#({z[  
 Yg3emn|a  
FROM titles dmE.yVI"O  
 ;kF+V*  
WHERE ytd_sales>10000 9GVv[/NAb  
 G9a6 $K)b  
) AS t Z;GZ?NOlY  
 Q>>II|~;J  
WHERE a.au_id=ta.au_id Q2!vO4!<N  
 i}e OWi  
AND ta.title_id=t.title_id ]kyGm2Ty9  
 3)a29uc:U  
此例中,将SELECT返回的结果集合给予一别名t,然后再从中检索数据。 }o-P   
 K~-XDLh5Nu  
(三)使用WHERE子句设置查询条件 wlM
?gQXU[  
 ~0|hobk  
WHERE子句设置查询条件,过滤掉不需要的数据行。例如下面语句查询年龄大于20的数据: KT71%?P  
 ($>0&w  
SELECT * CaBS0'
n  
 FOi`TZ8  
FROM usertable Pltju4.:C  
 TP::y  
WHERE age>20 VYo;[ue([  
 I;H9<o5  
WHERE子句可包括各种条件运算符: Els= :4  
 5Suc#0y  
比较运算符(大小比较):>、>=、=、<、<=、<>、!>、!< 	wtLMc  
 T
l(uqY?9  
范围运算符(表达式值是否在指定的范围):BETWEEN…AND… MPN=K|*  
 #/<Y!qV&  
NOT BETWEEN…AND… JSK5x(GlH  
 $4JX#lkt  
列表运算符(判断表达式是否为列表中的指定项):IN (项1,项2……) C&N4<2b  
 }#5roNH~Z  
NOT IN (项1,项2……) :~R
Fy?xRa  
 iGVb.=)  
模式匹配符(判断值是否与指定的字符通配格式相符):LIKE、NOT LIKE JBAK*g  
 3MJWC o-[  
空值判断符(判断表达式是否为空):IS NULL、NOT IS NULL xGv,%'u\  
 <|Eby!KXR  
逻辑运算符(用于多条件的逻辑连接):NOT、AND、OR +\vY; !^  
 7Sq{A@ET  
1、范围运算符例:age BETWEEN 10 AND 30相当于age>=10 AND age<=30 \'tz|  
 oHd0
<TO  
2、列表运算符例:country IN ('Germany','China') 6-14Htsk6  
 h=r<
B\Pa  
3、模式匹配符例:常用于模糊查找,它判断列值是否与指定的字符串格式相匹配。可用于char、 L00;rTs>  
 Tc5OI' -V  
varchar、text、ntext、datetime和smalldatetime等类型查询。 qS}RFM5|  
 dQ`ZrWd_U  
可使用以下通配字符: X3L[y\  
 ';|>`<  
百分号%:可匹配任意类型和长度的字符,如果是中文,请使用两个百分号即%%。 J~'Q^O3@  
 &\lS  
下划线_:匹配单个任意字符,它常用来限制表达式的字符长度。 	hIo S#]  
 _6S
b.9m  
方括号[]:指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。 _.*4Y  
 3/IWO4?_  
[^]:其取值也[] 相同,但它要求所匹配对象为指定字符以外的任一个字符。 r]O@HVbt$  
 1L=Qg4 H  
例如: n5*{hi  
 <Dj$0g  
限制以Publishing结尾,使用LIKE '%Publishing' QDgEJ%U-  
 &c?hJ8"  
限制以A开头:LIKE '[A]%' Q @OC =  
 a.dxgW[  
限制以A开头外:LIKE '[^A]%' 3auJ^B}  
 %v+fN?%x,d  
4、空值判断符例WHERE age IS NULL nL(%&z	\4  
 CVSsB:H6e  
5、逻辑运算符:优先级为NOT、AND、OR p1VahjRE-  
 'UvS3]bSYW  
(四)查询结果排序 +x9"#0|k;  
 5ih"Nds[H  
使用ORDER BY子句对查询返回的结果按一列或多列排序。ORDER BY子句的语法格式为: ,[}yf#8@J  
 @U
/3iDB\  
ORDER BY {column_name [ASC|DESC]} [,…n] e=n{f*KG`  
 m~j\?mb{+  
其中ASC表示升序,为默认值,DESC为降序。ORDER BY不能按ntext、text和image数据类型进行排 \abAPo  
 M$]O=2h+2  
序。 +G!jKta7B  
 x#j\"$dla  
例如: S-LZ(o{ZL  
 yhtvr5z1  
SELECT * m]=oaj@9  
 h\u0{!@}  
FROM usertable 4I#eC#"  
 8pq-nuf|K  
ORDER BY age desc,userid ASC  $nfBvf  
 wSJ]3gJM`  
另外,可以根据表达式进行排序。 #	+QWi0B  
 Oa}V>a  
  CmJ?_>  
 1t\b a1x  
二、联合查询 NO+
 55n  
 8R)D !	7[l  
UNION运算符可以将两个或两个以上上SELECT语句的查询结果集合合并成一个结果集合显示,即执行联 jI{~s]Q  
 mP)3cc5T  
合查询。UNION的语法格式为: jr[<i\!  
 I|	W'n-4Y  
select_statement 1~R$$P11[9  
 vhYMWfbY  
UNION [ALL] selectstatement (!0j4'   
  :PFx&  
[UNION [ALL] selectstatement][…n] +w	k]iH  
 s,$Z("B  
其中selectstatement为待联合的SELECT查询语句。 XJ:>UNf5;  
 _^6|^PT.  
ALL选项表示将所有行合并到结果集合中。不指定该项时,被联合查询结果集合中的重复行将只保留一 9RCO|J  
 $c@w$2  
行。 r)6uX  
 o9m  
联合查询时,查询结果的列标题为第一个查询语句的列标题。因此,要定义列标题必须在第一个查询语 UK"}}nO@e  
 H:q )^$s  
句中定义。要对联合查询结果排序时,也必须使用第一查询语句中的列名、列标题或者列序号。 '9*5-iO  
 n%0]V	Xx#  
在使用UNION 运算符时,应保证每个联合查询语句的选择列表中有相同数量的表达式,并且每个查询选 IP30y>\  
 atLV`U&t  
择表达式应具有相同的数据类型,或是可以自动将它们转换为相同的数据类型。在自动转换时,对于数值类 *%T)\\H2  
 zd*3R+>U'>  
型,系统将低精度的数据类型转换为高精度的数据类型。 @,x_i8  
 49+	>f  
在包括多个查询的UNION语句中,其执行顺序是自左至右,使用括号可以改变这一执行顺序。例如: ;m@1Ec@*p  
 J+)'-OFt0  
查询1 UNION (查询2 UNION 查询3) lX98"}  
  &jV9*  
  ex`
xkZ+  
  xl+DRPzl  
  yaH
Trh%  
 a
-xW 8  
三、连接查询 ]Q6+e(:~ZH  
 Aautih@LX  
通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于其它类型 AIZW@ Nq.5  
 @gt)P4yE  
数据库管理系统的一个标志。 Xh.+pJl,*  
 UGhW0X3k  
在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在 xn(+G$m  
 DE*MdfP0  
一个表中。当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。连接操作给用户带 )!'n&UxPo$  
 T)WZ_bR  
来很大的灵活性,他们可以在任何时候增加新的数据类型。为不同实体创建新的表,尔后通过连接进行 Y%<`;wK=^  
 /635B*g  
查询。 n,t6v5>88  
 j~M#Ss-H8  
连接可以在SELECT 语句的FROM子句或WHERE子句中建立,似是而非在FROM子句中指出连接时有助于 ;yF[2P	;  
 z^4KU\/JK  
将连接操作与WHERE子句中的搜索条件区分开来。所以,在Transact-SQL中推荐使用这种方法。 `S"W8_m  
 +"]oc{W!  
SQL-92标准所定义的FROM子句的连接语法格式为: JNh=fvO2i  
 eYJ{LPo  
FROM join_table join_type join_table ]e^R@w  
 ,LhEshf  
[ON (join_condition)] ~O \}/I28  
 pG/
NuImA  
其中join_table指出参与连接操作的表名,连接可以对同一个表操作,也可以对多表操作,对同一 C&=x3Cz  
 g[/^cJHQ  
个表操作的连接又称做自连接。 's)fO#
  
 Mv|vRx^b  
join_type 指出连接类型,可分为三种:内连接、外连接和交叉连接。内连接(INNER JOIN)使用比 $bk>kbl P  
 b.QpHrnhtK  
较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用 _ 1sP.0	t  
 M]c7D`%s  
的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。 XZ}de%U1  
 #nKRTb+{  
外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN) K} 
+S+
*_  
 "X`RQ6~]>  
和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹 hQXxG/yFm  
 _*Pfp+if  
配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的 &]w#z=5SXi  
 D/Rv&>Jh  
数据行。 |V	lMmaz  
 DB#$~(o  
交叉连接(CROSS JOIN)没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积,其结果集合中的 +4Q[N;[+*  
 lqF>=15  
数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。 pjACFVMFX  
 v{o? #Sk1  
连接操作中的ON (join_condition) 子句指出连接条件,它由被连接表中的列和比较运算符、逻辑 _	j~4+H  
 dsV ~|D6:  
运算符等构成。 z
OtkC3hY  
 [eyb7\#
  
无论哪种连接都不能对text、ntext和image数据类型列进行直接连接,但可以对这三种列进行间接 L/BHexOB  
 KGu= ;  
连接。例如: 3!aEClRtq  
 N	r<9u$d9=  
SELECT p1.pub_id,p2.pub_id,p1.pr_info 
=^Th[B  
 K5{{:NR$  
FROM pub_info AS p1 INNER JOIN pub_info AS p2 |)  O):  
 Rs2-94$!5  
ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info) )S2iIi;Bq  
 }t\
10nQ  
(一)内连接 B%fU'  
 *<r%aeG$em  
内连接查询操作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值。内连接分 iX{H,-C  
 'j }g   
三种: '*4iqPR;  
 ;}D-:J-z_  
1、等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接 -bA!PeI  
 wlr Ign%  
表中的所有列,包括其中的重复列。 ;1@C_5C  
 =5ug\S  
2、不等连接: 在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些 zks#EzQ  
 8"i/wMP]  
运算符包括>、>=、<=、<、!>、!<和<>。 9<l-NU9 _  
 3p_b8K_bG  
3、自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询 Aq"PG}Ic  
 _s*!
t   
结果集合中所包括的列,并删除连接表中的重复列。 Z(HZB  
 0~]QIdu{AR  
例,下面使用等值连接列出authors和publishers表中位于同一城市的作者和出版社: jn$j^51`C  
 \45(#H<$  
SELECT * yp p 4L|R  
 oIb)
Rq!m  
FROM authors AS a INNER JOIN publishers AS p )|RZa|`-G  
 y\#o2PVmY  
ON a.city=p.city 1"O&40l  
 C`0%C7  
又如使用自然连接,在选择列表中删除authors 和publishers 表中重复列(city和state): @8zT'/$  
 4gOgWBv  
SELECT a.*,p.pub_id,p.pub_name,p.country W`x)=y]Z  
 59i]  
FROM authors AS a INNER JOIN publishers AS p Fg=v6j4W  
 g\&2s,  
ON a.city=p.city ZoxS*Xk  
 U
Du~2%  
(二)外连接 Cw#V`70a  
 Pbe7SRdr^  
内连接时,返回查询结果集合中的仅是符合查询条件( WHERE 搜索条件或 HAVING 条件)和连接条件 \Yq0	zVol  
 l3p3tT3+  
的行。而采用外连接时,它返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外 5
`=KyHi:b  
 :B.G)M\  
连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行。 zQc"bcif5(  
 <KLg0L<W  
如下面使用左外连接将论坛内容和作者信息连接起来: Gw{+xz	KJ  
 L\L"mc|O  
SELECT a.*,b.* FROM luntan LEFT JOIN usertable as b yW("G-Nm  
 tS<h8g_  
ON a.username=b.username A(+:S"|@  
 8l23%iWxe  
下面使用全外连接将city表中的所有作者以及user表中的所有作者,以及他们所在的城市: )6{P8k4Zr  
 JIxiklk  
SELECT a.*,b.* lFfXWNb  
 "IwM:v  
FROM city as a FULL OUTER JOIN user as b $.:3$et@/  
 .zSD`v@[  
ON a.username=b.username 	rzu 
s  
 {mSJUK?TKl  
(三)交叉连接  FT.@1/ )  
 w$>3pQ8d  
交叉连接不带WHERE 子句,它返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数 w>vH8f  
 S}7>RHe  
据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。 O]qPmEj  
 *jF#^=  
例,titles表中有6类图书,而publishers表中有8家出版社,则下列交叉连接检索到的记录数将等 *Jt8  
 &fSTR-8ev#  
于6*8=48行。 Df@/cT  
 V@Wcb$mgk  
SELECT type,pub_name \hbiU]  
 @~o`#$*|  
FROM titles CROSS JOIN publishers D{C:d\ e)$  
 ce' TYkPM  
ORDER BY type