一、简单查询
9+QrTO
xp&!Cl>C3\
简单的Transact-SQL查询只包括选择列表、FROM子句和WHERE子句。它们分别说明所查询列、查询的 S=}~I
9oP{Al
表或视图、以及搜索条件等。 *d@Hnu"q
/[ ? F1Q
例如,下面的语句查询testtable表中姓名为“张三”的nickname字段和email字段。 ~vGtNMQg
=%\6}xPEl<
SELECT nickname,email EKPTDKut
;J(,F:N
FROM testtable rcZ SC3
Qu,k
WHERE name='张三' jw[BtRW
XKX,7
(一)选择列表 p'uz2/g
$ rYS
选择列表(select_list)指出所查询列,它可以是一组列名列表、星号、表达式、变量(包括局部变 &=Zg0Q
/>Vx*^u8Hz
量和全局变量)等构成。 HY4E
F2$bUY
1、选择所有列
<%D"eD
2<G1'7)
例如,下面语句显示testtable表中所有列的数据: q|X4[E|{Q
qffSq](D.
SELECT *
f_!`~`04
Tr0V6TS7
FROM testtable &H&P)Px*_
9S%gVNxn
2、选择部分列并指定它们的显示次序 Mlw9#H6
<aaDW
查询结果集合中数据的排列顺序与选择列表中所指定的列名排列顺序相同。 mRH]'dlD7
9JV
3
例如: 5TneuG[OD
Tud1xq
SELECT nickname,email y,?G75wij
J md
?
FROM testtable `b ")Bx|
*+j{9LK
3、更改列标题 2A}u qaF
/iy*3P,`
在选择列表中,可重新指定列标题。定义格式为: c^Jgr(Ow
0@K:Tq-mF
列标题=列名 B21AcE
g]<Z]R`
列名 列标题 OgN1{vRFx
L4pjh&+8
如果指定的列标题不是标准的标识符格式时,应使用引号定界符,例如,下列语句使用汉字显示列 =O#AOw`
G>,nZ/,A{
标题: %lJiM`a
5@D7/$bLp
SELECT 昵称=nickname,电子邮件=email $xtE+EV.p
yVI;s|jG
FROM testtable 7~ese+\smG
DRW.NL o
4、删除重复行 sV^h#g~Zb
S@xsAib0J
SELECT语句中使用ALL或DISTINCT选项来显示表中符合条件的所有行或删除其中重复的数据行,默认 pLQSG}N
!mxh]x<e
为ALL。使用DISTINCT选项时,对于所有重复的数据行在SELECT返回的结果集合中只保留一行。 o9LD6$
1O2h9I$bk
5、限制返回的行数 F|Dz]ar
]jVSsSv
使用TOP n [PERCENT]选项限制返回的数据行数,TOP n说明返回n行,而TOP n PERCENT时,说明n是 bp>ps@zFq
zrU$SWU
表示一百分数,指定返回的行数等于总行数的百分之几。 tOM3Gs~o6z
QHzX
5$IM
例如: xbrmPGpW$
{vT55i<mk
SELECT TOP 2 * X;6r$
to!W={S<ol
FROM testtable BgWz<k}5M
e#6&uFce
SELECT TOP 20 PERCENT * 5uV"g5?w
$',GkK{NX
FROM testtable Xc2B2c
!^l4EL5#
(二)FROM子句 g<iwxF
03QEXm~|Q
FROM子句指定SELECT语句查询及与查询相关的表或视图。在FROM子句中最多可指定256个表或视图, #1't"R+3M
^?X ^+
它们之间用逗号分隔。 j t`p<gI
7#9'2dI
在FROM子句同时指定多个表或视图时,如果选择列表中存在同名列,这时应使用对象名限定这些列 "26B4*
'^ e/F)0
所属的表或视图。例如在usertable和citytable表中同时存在cityid列,在查询两个表中的cityid时应 @CaD8%j{
B~ !G lT
使用下面语句格式加以限定: oA;jy
H@2v<e@
SELECT username,citytable.cityid V1`5D7Z
'hlB;z|T
FROM usertable,citytable c_G-R+
Jh&~/ntmm_
WHERE usertable.cityid=citytable.cityid 7 xp1\j0
)YnI!v2T
在FROM子句中可用以下两种格式为表或视图指定别名: @x=BJuUuX
PF'5z#] NP
表名 as 别名 1&% d
Y!a+#N!
表名 别名 eY4`k
SfZ=%6b7
例如上面语句可用表的别名格式表示为: !HR2Rf l
38U5^`
SELECT username,b.cityid XJJ[F|k~
V"7<[u]K|
FROM usertable a,citytable b < R|)5/9
GIC"-l1\
WHERE a.cityid=b.cityid 2-6.r_
/G)KkBC
SELECT不仅能从表或视图中检索数据,它还能够从其它查询语句所返回的结果集合中查询数据。 pKxX{i1l
y/@;c)1b9
例如: /+4^.Q*
FU5LYXCs
SELECT a.au_fname+a.au_lname lpfwlB'~9
\2R`q*a+
FROM authors a,titleauthor ta 4h;f>BG
{V%%^Zhwy
(SELECT title_id,title [/AdeR
k,;lyE
FROM titles Pu$kj"|q*[
0r0\b*r
WHERE ytd_sales>10000 <t[Z9s$n
W>?f^C!+m
) AS t K#l
-?
5DkK'tCI9Z
WHERE a.au_id=ta.au_id )4!CR /ao
Som.
qD
AND ta.title_id=t.title_id k+WO &g*|
*#Lsjk~_-
此例中,将SELECT返回的结果集合给予一别名t,然后再从中检索数据。 G>=9gSLM
iJ`%yg,
(三)使用WHERE子句设置查询条件 qXrt0s[
I
9{40_
WHERE子句设置查询条件,过滤掉不需要的数据行。例如下面语句查询年龄大于20的数据: A;fB6
-YzQ2#K
SELECT * 'ZGT`'ri
hF{x')(#l
FROM usertable jU]]:S4xD/
YW?7*go'Z
WHERE age>20 {k_ PMl0G
K2x6R
WHERE子句可包括各种条件运算符: d,Cz-.'sOf
0<]$v"`I
比较运算符(大小比较):>、>=、=、<、<=、<>、!>、!< 7m|`tjQ1
F@=e2e
4
范围运算符(表达式值是否在指定的范围):BETWEEN…AND… zj~nnfoys
io9y;S"+
NOT BETWEEN…AND… VM-qVd-
Q$xa
列表运算符(判断表达式是否为列表中的指定项):IN (项1,项2……) Em~7D]Y
V17>j0Ev$W
NOT IN (项1,项2……) 9tzoris[~
KjFZ
模式匹配符(判断值是否与指定的字符通配格式相符):LIKE、NOT LIKE ig{A[7qN
iUeV5cB
空值判断符(判断表达式是否为空):IS NULL、NOT IS NULL --in+
C2+{U
逻辑运算符(用于多条件的逻辑连接):NOT、AND、OR ?(5o@Xq
U8-Q'1IT&
1、范围运算符例:age BETWEEN 10 AND 30相当于age>=10 AND age<=30 j>$=SMc
pau*kMu^}
2、列表运算符例:country IN ('Germany','China') vF9*tK'
n9]IBIthe
3、模式匹配符例:常用于模糊查找,它判断列值是否与指定的字符串格式相匹配。可用于char、 <O \tC81
6Gs{nFw
varchar、text、ntext、datetime和smalldatetime等类型查询。 %^a]J"Ydi8
L!bfh`
可使用以下通配字符: Zz"I.$$[M
Rr o?q
百分号%:可匹配任意类型和长度的字符,如果是中文,请使用两个百分号即%%。 h]kn%?fpmB
Z"6 2#VM
下划线_:匹配单个任意字符,它常用来限制表达式的字符长度。 z$9@j2
t[]['Iosd
方括号[]:指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。 `Mg8]H~
Tg"'pO
[^]:其取值也[] 相同,但它要求所匹配对象为指定字符以外的任一个字符。 ]LEoOdDN"C
6uu^A9x
例如: 7))y}N:p
Q=d.y&4%
限制以Publishing结尾,使用LIKE '%Publishing' FX%t
4=u+ozCG
限制以A开头:LIKE '[A]%' N@k3$+ls
d>lt
限制以A开头外:LIKE '[^A]%' +<S9E'gT3V
zWy
,Om8P
4、空值判断符例WHERE age IS NULL If~95fy~c
W3De|V^
5、逻辑运算符:优先级为NOT、AND、OR CTl(_g
kcLj Kp
(四)查询结果排序 7]p>XAb
8h*t55
使用ORDER BY子句对查询返回的结果按一列或多列排序。ORDER BY子句的语法格式为: E)C.eW /
~'NX~<m
ORDER BY {column_name [ASC|DESC]} [,…n] yOX&cZ[
O {PW
其中ASC表示升序,为默认值,DESC为降序。ORDER BY不能按ntext、text和image数据类型进行排 nAIH`L"X
5JS ZLC
序。 xLA~1ZSVJw
}sf YCz
例如: )HEfU31IC
;c1relR2
SELECT * IZO@V1-m
Ba/RO36&c
FROM usertable 6XdWm
MMMqG`Px
ORDER BY age desc,userid ASC 5,S,\O9>X
*%:@
cbF-M
另外,可以根据表达式进行排序。 &svx@wW
^`tk/#h\9F
7e1dEgn
z<a$q3!#
二、联合查询 I`22Zwq:
LyGUvi
UNION运算符可以将两个或两个以上上SELECT语句的查询结果集合合并成一个结果集合显示,即执行联 yC
W*fIaq
Iha[Gu
合查询。UNION的语法格式为: h aCKv
92ZWU2"
select_statement ovo/!YJ2
CK2 B
UNION [ALL] selectstatement 5B1G?`]?
NeHx2m+
[UNION [ALL] selectstatement][…n] BYS lKTh
P^"R4T
其中selectstatement为待联合的SELECT查询语句。 M ~als3
RoX
&+~
ALL选项表示将所有行合并到结果集合中。不指定该项时,被联合查询结果集合中的重复行将只保留一 RL6Vkd?
4AQ[igTDP
行。 auRY|j
/-Wuq`P/ T
联合查询时,查询结果的列标题为第一个查询语句的列标题。因此,要定义列标题必须在第一个查询语 b6|Z"{TI
_
&M[MEO`t8
句中定义。要对联合查询结果排序时,也必须使用第一查询语句中的列名、列标题或者列序号。 )Nbc/nB$
!K[/L<
Kv
在使用UNION 运算符时,应保证每个联合查询语句的选择列表中有相同数量的表达式,并且每个查询选 |8bE9qt.P
lK*jhW?3:
择表达式应具有相同的数据类型,或是可以自动将它们转换为相同的数据类型。在自动转换时,对于数值类 80|onP\L
<|a=hHPi:
型,系统将低精度的数据类型转换为高精度的数据类型。 \^9pW 2v
EJ`Q8uz
在包括多个查询的UNION语句中,其执行顺序是自左至右,使用括号可以改变这一执行顺序。例如: !n eo\
s
_~IZ%+<.
查询1 UNION (查询2 UNION 查询3) _5b0wdB
q]TqI' o
bw9
nB{C<
J@QdieW6
vs+QbI6>-
wZjlHe
三、连接查询 fp{G|.SA
8.yCA
通过连接运算符可以实现多个表查询。连接是关系数据库模型的主要特点,也是它区别于其它类型 za T_d/?J
1fY>>*oP
数据库管理系统的一个标志。 )|pU.K9qZ
JdiP>KXV
在关系数据库管理系统中,表建立时各数据之间的关系不必确定,常把一个实体的所有信息存放在 Yrxk Kw#
ZYa\"zp-
一个表中。当检索数据时,通过连接操作查询出存放在多个表中的不同实体的信息。连接操作给用户带 G=|70pxU
:k~dj C
来很大的灵活性,他们可以在任何时候增加新的数据类型。为不同实体创建新的表,尔后通过连接进行 Nt~x&s
MGQ,\55"
查询。 Um z05*
y@3Q;~l,
连接可以在SELECT 语句的FROM子句或WHERE子句中建立,似是而非在FROM子句中指出连接时有助于 L6+C]t}>6
9/@ &*
将连接操作与WHERE子句中的搜索条件区分开来。所以,在Transact-SQL中推荐使用这种方法。 C',6%6P
[/cIUQ
SQL-92标准所定义的FROM子句的连接语法格式为: .xl.P7@JJ
i6Qb[\;
FROM join_table join_type join_table T#@{G,N
IE;\7r+h
[ON (join_condition)] $3k
"WlRG
n(>C'<otj
其中join_table指出参与连接操作的表名,连接可以对同一个表操作,也可以对多表操作,对同一 &RW`W)0;
2bLI%gg3
个表操作的连接又称做自连接。 r+S;B[Vd
@}DFp`~5|
join_type 指出连接类型,可分为三种:内连接、外连接和交叉连接。内连接(INNER JOIN)使用比 >F[GVmC
KQ{Lt?S
较运算符进行表间某(些)列数据的比较操作,并列出这些表中与连接条件相匹配的数据行。根据所使用 <
bFy(+
2n)gpLIJ
的比较方式不同,内连接又分为等值连接、自然连接和不等连接三种。 {q,?<zBzu
Qdu$Os
外连接分为左外连接(LEFT OUTER JOIN或LEFT JOIN)、右外连接(RIGHT OUTER JOIN或RIGHT JOIN) |9IC/C!HC
[jrqzB
和全外连接(FULL OUTER JOIN或FULL JOIN)三种。与内连接不同的是,外连接不只列出与连接条件相匹 T@P!L
6{=_718l`
配的行,而是列出左表(左外连接时)、右表(右外连接时)或两个表(全外连接时)中所有符合搜索条件的 vk'rA{x
8eJE>g1J
数据行。 ,q#2:b<E
#!})3_Qc(y
交叉连接(CROSS JOIN)没有WHERE 子句,它返回连接表中所有数据行的笛卡尔积,其结果集合中的 ^=+e?F`:{
YJ,*(A18
数据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。 }G'XkoI&
ubbnFE&PD
连接操作中的ON (join_condition) 子句指出连接条件,它由被连接表中的列和比较运算符、逻辑 G;s"h%Xw98
O~PChUU*Y
运算符等构成。 0Z
HDBh
&94W-zh
无论哪种连接都不能对text、ntext和image数据类型列进行直接连接,但可以对这三种列进行间接 c-B/~&
_TUm$#@Y`
连接。例如: s bnjy"Z%
}pawIf4V
SELECT p1.pub_id,p2.pub_id,p1.pr_info ()\jCNLT
9S>g6}[E#0
FROM pub_info AS p1 INNER JOIN pub_info AS p2 >zngJ$
c}-(. eu
ON DATALENGTH(p1.pr_info)=DATALENGTH(p2.pr_info) %>zjGF<
('hT
(一)内连接 6kR\xP]Kr
SK
R1E];4
内连接查询操作列出与连接条件匹配的数据行,它使用比较运算符比较被连接列的列值。内连接分 #jA) >z\Q^
1e}8LH7
三种: 0<.RA%dj
opp!0:jS*
1、等值连接:在连接条件中使用等于号(=)运算符比较被连接列的列值,其查询结果中列出被连接 .Djta|puu
sgAzL
表中的所有列,包括其中的重复列。 XAuI7e
"=A>}q@;H
2、不等连接: 在连接条件使用除等于运算符以外的其它比较运算符比较被连接的列的列值。这些 rs]I
HBiBv-=,
运算符包括>、>=、<=、<、!>、!<和<>。 ho.(v;
a#[-*ou`
3、自然连接:在连接条件中使用等于(=)运算符比较被连接列的列值,但它使用选择列表指出查询 3FNT|QF
=Op+v"
结果集合中所包括的列,并删除连接表中的重复列。 (D7$$!}
#;Tz[0
例,下面使用等值连接列出authors和publishers表中位于同一城市的作者和出版社: 4W;S=#1
(Rd$VYuf
SELECT * gzdG6"
obo&1Uv,/
FROM authors AS a INNER JOIN publishers AS p 80;n|nNB
FTf<c0
ON a.city=p.city P^)q=A8Z#
jc:s` 4
又如使用自然连接,在选择列表中删除authors 和publishers 表中重复列(city和state): \/5RL@X}
|+}G|hx@9
SELECT a.*,p.pub_id,p.pub_name,p.country lzhqcL"
vmX"+sHz$]
FROM authors AS a INNER JOIN publishers AS p L0NA*C
fU+Pn@'
ON a.city=p.city ,6,]#R
:J
m3.sVI0I
(二)外连接 -VT+O+9_A
)uheV,ZnY
内连接时,返回查询结果集合中的仅是符合查询条件( WHERE 搜索条件或 HAVING 条件)和连接条件 }}r>
K}
+TJEG?o
的行。而采用外连接时,它返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外 GP a`e
PaWr[ye
连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行。 $`J_:H%
#07!-)Gv
如下面使用左外连接将论坛内容和作者信息连接起来: xDLG=A%]z
o:p
*_>&
SELECT a.*,b.* FROM luntan LEFT JOIN usertable as b RU#F8O
1/Zh^foG
ON a.username=b.username ,wAz^cK|
$}o
b,i^W
下面使用全外连接将city表中的所有作者以及user表中的所有作者,以及他们所在的城市: tTanW2C
'LS z f/w
SELECT a.*,b.* bt/ =Kq#
y2|R.EU\m<
FROM city as a FULL OUTER JOIN user as b p $`92Be/
*>[3I}mM
ON a.username=b.username ]!
*[Q\
z-T{~{q
(三)交叉连接 $8~e}8dt|
Jkt4@h2Q}
交叉连接不带WHERE 子句,它返回被连接的两个表所有数据行的笛卡尔积,返回到结果集合中的数 =E*Gb[r_7
"TOa=Tt{,
据行数等于第一个表中符合查询条件的数据行数乘以第二个表中符合查询条件的数据行数。 nH-V{=**
O XP\R
例,titles表中有6类图书,而publishers表中有8家出版社,则下列交叉连接检索到的记录数将等 g(4bBa9y
n/4i|-^
于6*8=48行。 mY7>(M{
qxOi>v0\H
SELECT type,pub_name gl%`qf6:O
B&?sF" Y
FROM titles CROSS JOIN publishers &[[K"aM1
R[B?C;+(O
ORDER BY type