使用 HAVING 子句选择行
'o%ce2b5Y&\0 HAVING 子句对 GROUP BY 子句设置条件的方式与 WHERE 子句和 SELECT 语句交互的方式类似。WHERE 子句搜索条件在进行分组操作之前应用;而 HAVING 搜索条件在进行分组操作之后应用。HAVING 语法与 WHERE 语法类似,但 HAVING 可以包含聚合函数。HAVING 子句可以引用选择列表中出现的任意项。
51Testing软件测试网Ra}+R!Ms7F2e 下面的查询得到本年度截止到目前的销售额超过 $40,000 的出版商:
51Testing软件测试网R&J,w2b,q{| USE pubs
51Testing软件测试网4^G-xTp!M1mO SELECT pub_id, total = SUM(ytd_sales)
51Testing软件测试网qKk7Er@:qc FROM titles
C$t_Z-m?I0 GROUP BY pub_id
h"o(E9vRT0 HAVING SUM(ytd_sales) > 40000
51Testing软件测试网 eKGL[7WP 下面是结果集:
2U,e;KRB%x3S;S0 pub_id total
51Testing软件测试网[$p`
yQ_h ------ -----------
51Testing软件测试网:m"MiU*P Md Z;_#G5j 0877 44219
51Testing软件测试网 V}4ZB+Y&R3{ (1 row(s) affected)
51Testing软件测试网
XPXPr$P 为了确保对每个出版商的计算中至少包含六本书,下面示例使用 HAVING COUNT(*) > 5 消除返回的总数小于六本书的出版商:
51Testing软件测试网(e f9if$wly USE pubs
51Testing软件测试网0X$Gy#R8C+X SELECT pub_id, total = SUM(ytd_sales)
51Testing软件测试网{A)q*yV d FROM titles
51Testing软件测试网7@(g
lf ?j4L/z GROUP BY pub_id
51Testing软件测试网1i#`U5a]m3wr HAVING COUNT(pub_id) > 5
6g
hc?%eO|0 下面是结果集:
Yn%YqA0 pub_id total
F,q'P9G&JXT)r0 ------ -----------
51Testing软件测试网2k!P+hw!Q8r 0877 44219
51Testing软件测试网5V;E0W$Kavg`;D 1389 24941
|R]OD"P"U1{0 (2 row(s) affected)
51Testing软件测试网%\d2j#MY8[ M 理解应用 WHERE、GROUP BY 和 HAVING 子句的正确序列对编写高效的查询代码会有所帮助:
Er*F.K]lv4F0 WHERE 子句用来筛选 FROM 子句中指定的操作所产生的行。
51Testing软件测试网uR-o#U"t&} GROUP BY 子句用来分组 WHERE 子句的输出。
^]&[C)rt.QX)Du0 HAVING 子句用来从分组的结果中筛选行。
*?mi+O4mPei K
r0 对于可以在分组操作之前或之后应用的搜索条件,在 WHERE 子句中指定它们更有效。这样可以减少必须分组的行数。应当在 HAVING 子句中指定的搜索条件只是那些必须在执行分组操作之后应用的搜索条件。
51Testing软件测试网YQr(h$O.V Microsoft®
SQL Server™ 2000 查询优化器可处理这些条件中的大多数。如果查询优化器确定 HAVING 搜索条件可以在分组操作之前应用,那么它就会在分组之前应用。查询优化器可能无法识别所有可以在分组操作之前应用的 HAVING 搜索条件。建议将所有这些搜索条件放在 WHERE 子句中而不是 HAVING 子句中。
2["r6n&w8tV0 以下查询显示包含聚合函数的 HAVING 子句。该子句按类型分组 titles 表中的行,并且消除只包含一本书的组:
51Testing软件测试网AI4NqD USE pubs
51Testing软件测试网} x&iUO T&Z SELECT type
51Testing软件测试网-H6[a,{Hs.S(~ FROM titles
51Testing软件测试网qH(wRN[@-pz GROUP BY type
51Testing软件测试网NT4Qn i#W5T$| HAVING COUNT(type) > 1
_NA.^gPo2n0 下面是结果集:
W+`2dN/S#|/d0 type
51Testing软件测试网m;zNu1^Gz-h ------------------
51Testing软件测试网%Sn.k
i+h:Z business
y9Cl)W'~0 mod_cook
51Testing软件测试网R
ko]!pP%d b'e popular_comp
-{-fbjN+x!r0 psychology
51Testing软件测试网~v,npf!I;A trad_cook
51Testing软件测试网5A6w%b)Q|[xnt (5 row(s) affected)
51Testing软件测试网 j
ax5vwEn 以下是没有聚合函数的 HAVING 子句的示例。该子句按类型分组 titles 表中的行,并且消除不是以字母 p 开头的那些类型。
51Testing软件测试网
Wh;?E2Z Tz+bp USE pubs
51Testing软件测试网biAdh,b,e:Gy#fV SELECT type
?2{,Y!Hq5v_5t0 FROM titles
cJ4v6C,}_*QB5`0 GROUP BY type
!as/p-TQU7_
q+}0 HAVING type = '%p%'
m ?'Y&z:Ob(sn0 下面是结果集:
P/H6M2f5jwG#F"A0 type
^)GW)~Vv0 ------------------
51Testing软件测试网VSo6F"x%}9\/`9v popular_comp
51Testing软件测试网-j8isYbw'ddR psychology
eK6s8~;A_ b0 (2 row(s) affected)
51Testing软件测试网JfW*`.z 如果 HAVING 中包含多个条件,那么这些条件将通过 AND、OR 或 NOT 组合在一起。以下示例显示如何按出版商分组 titles,只包括那些标识号大于 0800、支付的总预付款已超过 $15,000 且销售书籍的平均价格小于 $20 的出版商。
51Testing软件测试网%@(r/Ka:PC0?2m SELECT pub_id, SUM(advance) AS AmountAdvanced,
51Testing软件测试网 Ot9[J
A7o:L:AK AVG(price) AS AveragePrice
(OTf*g_E.u'Q[r0 FROM pubs.dbo.titles
;_nvu1[aP0 WHERE pub_id > '0800'
b)?xd)T6r4W`f"m0 GROUP BY pub_id
yKQ-W$Qu9U0 HAVING SUM(advance) > 15000
-Oy1bh*^I/ur0 AND AVG(price) < 20
n,P[8yuqu.t0 ORDER BY 可以用来为 GROUP BY 子句的输出排序。下面的示例显示使用 ORDER BY 子句以定义返回 GROUP BY 子句中的行的顺序:
51Testing软件测试网*^3\At7Y+z SELECT pub_id, SUM(advance) AS AmountAdvanced,
K!X'r0d%o1X^~A0 AVG(price) AS AveragePrice
51Testing软件测试网X+}:_'I0B Ye FROM pubs.dbo.titles
51Testing软件测试网3Zu8v&~9reY WHERE pub_id > '0800'
w
wg d&J"iW`'p0 AND price >= 5
TL1{D2G!Vb0 GROUP BY pub_id
qY-B8v7hZj7a)P4jQ0 HAVING SUM(advance) > 15000
51Testing软件测试网[$c_R,G3ITGw| AND AVG(price) < 20
51Testing软件测试网xx#RL(d[/b ORDER BY pub_id DESC
51Testing软件测试网M/t;I.IKk0R5I*_