查询之order by,group by和having的使用 (转)

上一篇 / 下一篇  2009-09-25 19:26:47 / 个人分类:数据库

(1)order by
\k i7gY^6Oy:n0
Y2Q;Zn3X0 ORDER BY子句的语法为:
;R.N oYh(d%F+zn0
(P%Z%HP X(b2q0SELECT column1, SUM(column2) FROM "list-of-tables"
z F4R!b5_;TG051Testing软件测试网*?,`J\wW(Z~
ORDER BY "column-list" [ASC | DESC];
9xr-Ed O*e W0
yi1ae q}0[ ] = optional
'G#c3V orp051Testing软件测试网!p/]@ jMoKX%N
ORDER BY是一个可选的子句,它允许你根据指定要order by的列来以上升或者下降的顺序来显示查询的结果。例如:
W q,QGn3{"~6\0
Q uW#{y!v0ASC = Ascending Order – 这个是缺省的
Z*O ^_:z,xx Q051Testing软件测试网|r sr+{ d-g_
DESC = Descending Order51Testing软件测试网wUk C4G;L }+`O&l ]T]
51Testing软件测试网"j*~ r6oU cl a `h
下面举个例子:51Testing软件测试网.S*y^/Kgc
51Testing软件测试网d*q Z!N.L`R f
SELECT employee_id, dept, name, age, salary
p2u(wE8D_0
MW8|*J"O$x8gQ$n#x,d0FROM employee_info51Testing软件测试网"k!K9v6w2B-Ex I
51Testing软件测试网o7C[ u$j&N [%s{c
WHERE dept = 'Sales'51Testing软件测试网l4R2Pul4K9~`2F@
51Testing软件测试网W ]M2CF%i\;aO
ORDER BY salary;51Testing软件测试网5ZTb#LA9n ? W3M
51Testing软件测试网'k?R8kLb%H*{O*X5p
这条SQL语句将从employee_info表中列dept等于'Sales'选择employee_id,、dept、 name、 age和 salary,并且根据他们的salary按升序的顺序来列出检索结果。51Testing软件测试网&K5}-q'u Z7Z_){h
51Testing软件测试网4m:GZ$y;k-v ABY
如果你想对多列排序的话,那么在列与列之间要加上逗号,比如 :51Testing软件测试网A@(C H0a ae

@8ND:GU"_ s i\0SELECT employee_id, dept, name, age, salary51Testing软件测试网X_T6oN%`
51Testing软件测试网s!F:p u3GZ c h_6`
FROM employee_info
MVT d2mL:A&};\V051Testing软件测试网l;O0O8H.wk
WHERE dept = 'Sales'
$D4q2xjL"?`Ft\#V051Testing软件测试网/@L0e_.LO:` x
ORDER BY salary, age DESC;51Testing软件测试网7B.se\j*tx

5Rt[T$p`0(2)group by51Testing软件测试网"iGe |F2Dg+m
51Testing软件测试网5{8ts'w(F r
一、首先讲讲GROUP BY 子句语法:
? Z)]D-I M9W051Testing软件测试网W)Y0un O V8p
SELECT column1, SUM(column2) FROM "list-of-tables"
J"KH)zY1dXh`k0
:U,n XY(EQv0GROUP BY "column-list";51Testing软件测试网$C1B+e2{K;[/teu
51Testing软件测试网G!Uq)N8] ^0@!Z ?Q E
这个GROUP BY子句将集中所有的行在一起,它包含了指定列的数据以及允许合计函数来计算一个或者多个列。当然最好解释的方法是给出一个例子啦:51Testing软件测试网/?@9W8w5n^#e @Ah

3u:FJ L3P S$h0假设我们将从employee表中搜索工资最高的列,可以使用以下的SQL语句:51Testing软件测试网7\k;{ G(A/oH#v1d

:h yXI^~0SELECT max(salary), dept51Testing软件测试网wmi}6q'E"nZn
51Testing软件测试网1p-R;}{7L3F
FROM employee51Testing软件测试网 |X5c m3B5yV
51Testing软件测试网 KFZ-zfQ-utxI
GROUP BY dept;
,@Q @cX#W$Fd0
)z_.D(vM n n0这条语句将在每一个单独的部门中选择工资最高的工资。结果他们的salary和dept将被返回。
4WBAQl`g'`gCC051Testing软件测试网2@kwZD%N
二、group by 从英文里理解就是分组。必须有“聚合函数”来配合才能使用,使用时至少需要一个分组标志字段。51Testing软件测试网%O8Y8\-U.Vtv
 
T B5b`-e-}0什么是“聚合函数”?
DI$] _I:_0e,|G-V0  像sum()、count()、avg()等都是“聚合函数”51Testing软件测试网(H1s.@ozF
  使用group by 的目的就是要将数据分类汇总。
m)K;j |a0x0}0
,j#_*b"M.l{Q u@ n-W0  一般如:51Testing软件测试网)?%Z.@m&cMIV+Z ZxC
    select 单位名称,count(职工id),sum(职工工资) form. [某表]51Testing软件测试网g _(j4ve$? D"A
    group by 单位名称
F(t*Hl6CI9JC0    这样的运行结果就是以“单位名称”为分类标志统计各单位的职工人数和工资总额。51Testing软件测试网Z9}];|Yks!}

&XR1U2W(nD"@0  在sql命令格式使用的先后顺序上,group by 先于 order by。51Testing软件测试网 A&X`n `~7?4G
 51Testing软件测试网 y9e)T~.H)P0{Q3A*]0\
  select 命令的标准格式如下:51Testing软件测试网6cx`7_@4_8fZ'w0K!J
 
_~(Q*gp0   SELECT select_list51Testing软件测试网va}6kO K$S
   [ INTO new_table ]
&d(@Rv1p4r Xg0   FROM table_source51Testing软件测试网;k6Gb/r*F&Ap
   [ WHERE search_condition ]
$|;?2EZ J5@f0   [ GROUP BY group_by_expression ]
Z#H_ ]e N?h0   [ HAVING search_condition ]
H&Cn0m7x"}0   [ ORDER BY order_expression [ ASC | DESC ] ]51Testing软件测试网])l7R&z})a
51Testing软件测试网qA1`?iZ9B
三、理解group by:
g@ i*xa#VAf i0
O!i#g"r G Gyv`0表1:
w}0C8pmq0
GR U.Fz#tw G+FK\ s0 type
:@ M x0W8Kw!on0   51Testing软件测试网![0mo*bT za4j |;}
 udate
VW1OZo\0^0
ile` lB F^.w0 mp3
r?$K*Y!]1jPPk0   
5Zl%B p u h-UKi0 2006-3-251Testing软件测试网%Yp jW To? eb
51Testing软件测试网$g7eoBN1qxr
 flash  
kze3G1h0
`/e&~ls2x+g5TsZ:l.f*~0 2006-1-251Testing软件测试网&df nzM0\t

] t*Viir0 mp351Testing软件测试网,R whf2FS&KuD*i
   51Testing软件测试网 Ph0bX(x~]
 2006-2-251Testing软件测试网7{4~U/Yu)g4|,zz
 
g,W,sb)q0在表1中,假设要取出最后更新的某一类型(type)产品的日期51Testing软件测试网f[WW!BLC9B
那么就要使用group by type的方式
%b)]:yjLP{Yv0select type from 表1 group by type
Tc`}.Z:@"P_,]0但这样就无法读到udate
$Uc-o wr^k0 51Testing软件测试网f y!Vg!QX
再来51Testing软件测试网S alf#BgY6r
select type,udate from 表1 group by type51Testing软件测试网F4t&Ic2vMk(UB,j
这种写法是错误的。51Testing软件测试网0a$^8Vs5[f5v*S
原因是type和udate 不是一对一的关系。就是说一种type有几个udate51Testing软件测试网P9`8m8R4eg
所以51Testing软件测试网&H;Cy S.{$Y%Ms \
selct ** group by ** 之后没办法组织形成新的表,不知道要取哪个udate
fF(\ U(U oo%OE6w0 51Testing软件测试网~!jj.G@
再来51Testing软件测试网ILvJr1v6p\
select type,max(udate) from 表1 group by type51Testing软件测试网 Ks%P/S:y5` z3M&kkZ
这样就正确了。
6~X*H$y\ H0取的是最大的udate ,一对一成立。
B\C:f ]:l*n H0
1~F s,d[]Yb0四、GROUP BY... 被附加于SQL 是因为聚会函数 (如 SUM) 每次都返回所有列值的合计,没有GROUP BY函数是不可能找到列值的单个分组的合计数。
1g%E'fV?'CW x2x0
mf*GrE'E z0语法
h Ov3lu({6p'X^;|051Testing软件测试网 o E{r3p }|dU\
SELECT column,SUM(column) FROM table GROUP BY column51Testing软件测试网$z6N{#T)dsv[

? c_F lA#I$W0-----------------------------------------------
|X COP h0GROUP BY 示例
^8_m0^*bko]Y0这个 "Sales" 表:51Testing软件测试网/Pr#Ni$Q4g
51Testing软件测试网}SP;@ d$S4v2i\O
Company     Amount51Testing软件测试网0iW ru-on:N
W3Schools     5500
V;w'bU o}^%H0IBM    4500
M5x$YP$QX"vC0W3Schools     710051Testing软件测试网Q Tk9KnLG:u'e E H

7U Jy,P7MDi*w0和这个SQL语句:51Testing软件测试网)T0^6CD^-JEB_&s
51Testing软件测试网2L0imb3J;mg o
SELECT Company, SUM(Amount) FROM Sales51Testing软件测试网 }6R8pd8] W#G7y#A
51Testing软件测试网c#Z4Y4V4Nb\
返回这个结果:
l&Z EyT051Testing软件测试网 y'aM[3@9O9h5A Z
Company     SUM(Amount)51Testing软件测试网!CV(FU E_r r0Gp
W3Schools     17100
yLo7`)o)`I)E0IBM     17100
Th$\Ca;_?%|3Dd.\0W3Schools     17100
"W&BzD:C#a4uqn0
(p+H;r%V D"SW0上面的代码是不正确的,因为被返回的列不是部分合计。GROUP BY 子句将解决这个问题。51Testing软件测试网&i cUA,R#{7[N

R?YqZ$I0SELECT Company,SUM(Amount) FROM Sales            GROUP BY Company51Testing软件测试网l1n}{5?&I)K%p.LS S

,Cw"Dp[.s3]0返回结果:
f$q qS#\0
$r0W,_)L9|V&FU0Company     SUM(Amount)51Testing软件测试网U'I7k`Lv
W3Schools     12600
E%A)W!z7]+^7vz0IBM     450051Testing软件测试网#dm'pw9h
51Testing软件测试网`o)z&yn5~%{Ii
五、
(tlAD/|~0SQL Group by学习及相关应注意的地方51Testing软件测试网.d6D4E x#}(v7s7Wu
 
p7\i f)D4E*E [0    在select 语句中可以使用group by 子句将行划分成较小的组,然后,使用聚组函数返回每一个组的汇总信息,另外,可以使用having子句限制返回的结果集。group by 子句可以将查询结果分组,并返回行的汇总信息Oracle 按照group by 子句中指定的表达式的值分组查询结果。
"l-X;Ar od~0
b,LEkHk(e[0   在带有group by 子句的查询语句中,在select 列表中指定的列要么是group by 子句中指定的列,要么包含聚组函数51Testing软件测试网:~d X X5u7|
51Testing软件测试网~U`-u R+L^&t*qG
   select max(sal),job emp group by job;51Testing软件测试网E#Q9H{4l{~-?7]9A'z
   (注意max(sal),job的job并非一定要出现,但有意义)51Testing软件测试网@ Gs?ogl
51Testing软件测试网;}@ Wde2I@`P;G0p
   查询语句的select 和group by ,having 子句是聚组函数唯一出现的地方,在where 子句中不能使用聚组函数。51Testing软件测试网 F9[1zB)}"y}
51Testing软件测试网 ~f^8p$So1_
  select deptno,sum(sal) from emp where sal>1200 group by deptno having sum(sal)>8500 order by deptno;
NYaC9h0
t;z1rRx9e w.xP0  当在gropu by 子句中使用having 子句时,查询结果中只返回满足having条件的组。在一个sql语句中可以有where子句和having子句。having 与where 子句类似,均用于设置限定条件
-z V(n-`7X+z'~H p#u}0 51Testing软件测试网 b1n1MFM zA
  where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。51Testing软件测试网r4\ ]0OT3R/vb q
  having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组。
3{C1vucf"X"Mc051Testing软件测试网@g+\ZY7t G7s2^
  查询每个部门的每种职位的雇员数51Testing软件测试网Rt"AvK'T(g-U
  select deptno,job,count(*) from emp group by deptno,job;51Testing软件测试网5|C(h0C y|N1Ml4\2L

5t7X,@9D$Kv0注意:51Testing软件测试网Mk^&y*s

0Le`(zhOdK0        group by 不能对别名进行分组排序.举例如下:
4TEa[/g-bE051Testing软件测试网&U h$S&f h w
错误SQL:51Testing软件测试网GE9\0e9af

j w*O&oY3To0SELECT to_char(BASICROLL.ROLLDATE,'yyyy-mm') AS YEARDATE,51Testing软件测试网3r9q;Q vm7d T:E{ U5O h

6N!A[.IS0   DEPTDICT.CNNAME DEPTNAME,
&[1l T8h,p4N0    COUNT(BASICROLL.ID) AS PROJCOUNT
F%ice#@%QNX_0
rZ lN(j U&Md0FROM BASICROLL LEFT JOIN DEPTDICT ON BASICROLL.ARRDEPTDICTID=DEPTDICT.ID51Testing软件测试网:v;H o3OIB

+fjs"tVB0WHERE DEPTDICT.CNNAME <> '无'
T[VUH A/m} u0
Q7FT6@"Y-lSn]*@,g w0GROUP BY YEARDATE, DEPTDICT.CNNAME                      151Testing软件测试网7Kw3`@$?-d Y3j
ORDER BY YEARDATE DESC                                                  2
&d7Z'r7|Qs2x"|051Testing软件测试网v,jWF2y^O~.g:N
 作者原意是将记录按年月,部门进行分组.并倒序排序.但上面的GROUP BY因为用了别名,所以会提示SQL语法错误.如果将上面1,2二句改成:   
7DUhM K0
"@.?'Wxa uw^D0GROUP BY BASICROLL.ROLLDATE, DEPTDICT.CNNAME                      351Testing软件测试网 z P7k hYQt tE
51Testing软件测试网G$Z-BgH1tw@K|
ORDER BY BASICROLL.ROLLDATE  DESC                                                4
pk){ `h1i/Fz0
X kJ6^3go0如上3,4二句,又会不合原意,因为BASICROLL.ROLLDATE  包括了年月日.这样分组得出的是按年月日来分组,而不是单纯的年月了.所以正确的SQL应该是这样的.
cFO"U2_@+O0{$O8w051Testing软件测试网~-P6b:f}*X)R)t1sy
正确的SQL51Testing软件测试网F[)kc ]A

Ih.V jh&Y l0SELECT to_char(BASICROLL.ROLLDATE,'yyyy-mm') AS YEARDATE,
hx&jv7U*o ~,K0
8c;{&uvbj#dkJ0   DEPTDICT.CNNAME DEPTNAME,51Testing软件测试网 d9yZ@:vYI7h3b
    COUNT(BASICROLL.ID) AS PROJCOUNT51Testing软件测试网j K.b7H;@l{r

-d?;^Pu6i.oq0FROM BASICROLL LEFT JOIN DEPTDICT ON BASICROLL.ARRDEPTDICTID=DEPTDICT.ID51Testing软件测试网:j E9IP&Sz
51Testing软件测试网g5JPB BE vF
WHERE DEPTDICT.CNNAME <> '无'51Testing软件测试网m n/_LEa

+\4g%vd.i4`3n,K0GROUP BY to_char(BASICROLL.ROLLDATE,'yyyy-mm'), DEPTDICT.CNNAME                     
$C3R \dtQ051Testing软件测试网?-]d$_&o3T
ORDER BY to_char(BASICROLL.ROLLDATE,'yyyy-mm') DESC                                                 51Testing软件测试网o$rw ] m
以上的注意部分为本人在项目开发过程中经验所得.
@$a!}RwYQ0
2R d(i0G.Ad0来自:http://gyapollo.yculblog.com/post.1116750.html51Testing软件测试网M w fZi
51Testing软件测试网~2iH0]+t
六、例子
A5H.d7TWl9z6x/B`/u0
Of5pu1u o01> select * from bank_info
^.Y.xq6G ncz02> go
_ Y b@O4G0 bankno acctround
&n(r3tT5M^b&s B$c0 ------ ---------51Testing软件测试网4[a8SS;j
 123456 1        
s0awy$tN c]0p0 123456 2       
0eNlMD"qo051Testing软件测试网)C;bJd'gr%f
(2 rows affected)51Testing软件测试网U:[?qoQ)B(b eZ
1> select * from bank_info where acctround='1' group by bankno order by bankno
C4l hvyAb-a/t02> go51Testing软件测试网+HP6WF{d
 bankno acctround
liYdCe%Q0 ------ ---------
?r4JgX&` W0 123456 1        
[g zXFKcB0 123456 2        
f Ox r P)p%M051Testing软件测试网#}V;^2r Qo
(2 rows affected)
@[R7Wo2MC dM01> select * from bank_info where acctround='1' order by bankno51Testing软件测试网+sk$s/Bd'q
2> go
(v5s3^n |+X'yI0 bankno acctround
8s],A glp0 ------ ---------
},}K3U.C/s.x i$M0 123456 1        
qS8q-F*F @x6`']051Testing软件测试网#LM@ME;t u$A
(1 row affected)51Testing软件测试网9D ]qw$B
1> select * from bank_info51Testing软件测试网3y"| nPyGN a&h
2> go
f4BZ9s1|9q0 bankno acctround
a#t1i'X~r8Gu0 ------ ---------51Testing软件测试网l+YP%FK/I6H+l^
 123456 1        51Testing软件测试网+q/u%x9~0o J'y
 123456 2        51Testing软件测试网[}HRaZi[
51Testing软件测试网M7wOupIY3r
(2 rows affected)
ei._m0^!n01> select * from bank_info where acctround='1' group by bankno,acctround order by bankno51Testing软件测试网H+gB,F-JA#~,bD
2> go51Testing软件测试网1Fob)i@A
 bankno acctround
Y s@)\-cFF0 ------ ---------51Testing软件测试网4O u2w@aqa:YNkI r-i
 123456 1        51Testing软件测试网@vqpq%h3F%Q

O4ht^D I6pr@0(1 row affected)
NCh7S!gYA y051Testing软件测试网.yb$|:B S.zS'C3o
group by bankno,acctround的意思是找出bankno,acctround两列完全相同的不同行作为一组.那上面的数据就分成两组了,因为 acctround不同,而结果需要acctround='1'的组.所以只有一行结果.如果是group by bankno,那么两行会合成一行.它并没有先通过where分析出只有一行符合结果集,再group就只有一行结果了.这里的问题是where和 group谁先谁后分析的问题?在这个问题的上下文中,本来的group by bankno就没有任何意义.其实是这样的:51Testing软件测试网8w l~3t-kE6Qy_Q@

[!SY)s#d_5q"x8]0或者是:51Testing软件测试网 mdh |.Akb}0w0Q v
51Testing软件测试网{.sZmRb
select bankno,sum(money) from bankdiff group by bankno;
"pg r$@&dDB&l:D051Testing软件测试网M!lJL0Nq
又或者是:51Testing软件测试网2k;P9i;{ U%`

#Rd ~ c;o9nG0select bankno,acctround,sum(money) from bankdiff where acctround='1' group by bankno,acctround;
EBQ&^ V)[-j3|(Q0 
qj`(p X0A*Lw(n+z.q0不可能指定acctround又不把它放在groub by中的.51Testing软件测试网\1_d"w si
51Testing软件测试网LLQqZs
1> select * from bank_info group by bankno51Testing软件测试网&YW(L+U+@9H:y9Z"[*a0C}
2> go51Testing软件测试网bR^2}m4PLw
 bankno acctround51Testing软件测试网`8j/d^ h)ORZm&`Lk
 ------ ---------51Testing软件测试网}X/_R0o#B J3q;{
 123456 1        
g K}~a0 123456 251Testing软件测试网.c j vr!N ~*M;I
51Testing软件测试网 ^P Y5[dJ6@
可见这个group by没有意义.因为它有select *,而acctround不一样,就不能只显示一行出来.把select * 改成 select bankno就只有一行结果了.51Testing软件测试网,\I:MVtE
51Testing软件测试网#b[ XvL\Z/C
总 结:使用group by必需明确你分组的意义,是否有必要这一个列或几个列来确定一个有意义的组,而需要显示的结果行的列是否和group by子句中的列名相冲突.一般不在group by子句中的列名都不会直接在select中显示出来.因为它们要分成一组来或者做些运算再显示.如sum(money)等.51Testing软件测试网0]@ ~,d7\.~-otc']
51Testing软件测试网ktEG/T4} rW k
(3)having
s{M&}8E;lB N051Testing软件测试网)q B2I X4R,n
一、下面先给出HAVING子句的语法:51Testing软件测试网I Yq*b&t[D | }
51Testing软件测试网5I7O0YI+d
SELECT column1, SUM(column2) FROM "list-of-tables"51Testing软件测试网a#Ea M8b}^O

?t.] L3o$^A0GROUP BY "column-list"
?'rZkK8@4GR051Testing软件测试网r0sAM!_DJ
HAVING "condition";
6W)@Cg;]|!~BlM q051Testing软件测试网2E0g)v2x9|$]'T b
这个HAVING子句允许你为每一个组指定条件,换句话说,可以根据你指定的条件来选择行。如果你想使用HAVING子句的话,它应该处再GROUP BY子句之后。51Testing软件测试网S+Gg PQ W i5Vm uP

`/zqn Yn|6~0下面将以一个例子来解释HAVING子句。假设我们的employee表中包含雇员的name、departmen、salary和age。如果你想为每个部门中每个雇员选择平均工资的话,你可以使用下面的SQL语句:51Testing软件测试网QfMo/Wz

I[*|(a ~0SELECT dept, avg(salary)51Testing软件测试网'm!Bcj]6_

?Qos-w2y w5w0FROM employee
8Deu(A,~I}@5}Rt051Testing软件测试网4~8Q)|P4s,l!h1s(RM
GROUP BY dept;51Testing软件测试网&z#V+UFi'VI;^%v
51Testing软件测试网c,ST8nje
当然,如果你还想只计算和显示salary大于20000的平均工资的话,你还可以加上HAVING子句:51Testing软件测试网_y8b[v Ny

6o#QLL_%\#l:N0SELECT dept, avg(salary)
)T m/dMq'f051Testing软件测试网}*Q)czE
FROM employee51Testing软件测试网 E$b:VYx%S!v\
51Testing软件测试网+iYY8C:ck"T hQv
GROUP BY dept51Testing软件测试网;w i'u5s%i0H ]R

N Iq)a0`L3o@0HAVING avg(salary) > 20000;
_z;d~Lh_051Testing软件测试网1i{9j j.AGJ/Q+z:z
二、HAVING... 被附加到SQL语句是因为WHER关键字不能被用于聚会函数 (如 SUM),并且没有HAVING...它将不可能测试结果条件。
t{8vzx7m E|d"o051Testing软件测试网.uZA,l2n3U
语法:
'd%m4T'i9z#@rYX051Testing软件测试网H5T r6pZ
SELECT column,SUM(column) FROM table            GROUP BY column            HAVING SUM(column) condition value
M/K-xx(R\t]o1T1j051Testing软件测试网#d0}k%gJQ/z!Pg
这个 "Sales" 表:51Testing软件测试网\k|/OZr"Q+f t
51Testing软件测试网.G*h]$n x3X q
Company     Amount
eNR En(d;h!}-c5Q0W3Schools     550051Testing软件测试网 r5P]m"}(u
IBM     450051Testing软件测试网 n&x#iPx
W3Schools     710051Testing软件测试网 N!y5R*dU4_-i/K R
51Testing软件测试网%];B*h AZ]:[ un @
和这个SQL语句:
8G4]{}-f$K Q051Testing软件测试网po+dQ.u _#@
SELECT Company,SUM(Amount) FROM Sales            GROUP BY Company            HAVING SUM(Amount)>1000051Testing软件测试网/@&Zq*V#K,Np0K`/[

Z2qVOJ+j0x0返回这个结果
"s*y-Vytv0T%q/R051Testing软件测试网0m1K5GY ?"G+N udu
Company     SUM(Amount)
^)L2{g3s%B0W3Schools     12600

TAG: 数据库 having

 

评分:0

我来说两句

Open Toolbar