高效使用SQL GROUP BY,SUM,COUNT
技术问答
376 人阅读
|
0 人回复
|
2023-09-12
|
我有一个产品销售表,看起来可能如下:
4 H, L8 z+ c$ S ~: I" uproduct | amount | ptype | pdate p | 1.00 | sale | 01/01p | 2.00 | base | 01/02p2 | 1.50 | sale | 02/03p3 | 5.25 | base | 10/10我想建立一个表格,每行显示一个产品,总金额,如果产品是唯一的,显示类型,否则类型显示为+ x2 Q- V& W) u# D5 B
VAR,如果产品是唯一的,则显示日期,否则显示日期为NULL。结果如下:% n% ^+ T3 a& [1 J- @: |# J
product | total | ptype | pdate p | 3.00 | VAR | (NULL)p2 | 1.50 | sale | 02/03p3 | 5.25 | base | 10/10我通过执行以下操作来完成所需的结果:
& t" K4 H3 j7 x; L. W: Y7 ^# WSELECT DISTINCT product,(SELECT SUM(amount) FROM T as b GROUP BY b.product HAVING a.product = b.product ) as total,(SELECT CASE WHEN COUNT(*) = 1 THEN a.ptype ELSE 'VAR' END from T as b GROUP BY b.product HAVING a.product = b.product) as ptype,(SELECT CASE WHEN COUNT(*) = 1 THEN a.pdate ELSE NULL END from T as b GROUP BY b.product HAVING a.product = b.product) as pdateFROM T as a但我想知道是否有更有效的方法来达到同样的结果。* h( M: ~# J8 A% g
, A+ `- E' h3 [' w2 m' {$ H
解决方案:
: q/ D. c! ^7 z& ^7 a 无需使用任何形式的子查询或内联视图。这些结构可能对数据库引擎的复杂性产生负面影响。- Y4 F% G- {6 _' u I. o8 t* {
这就是你的要求,即使是最原始的SQL在发动机上,只需扫描一次表就可以可靠地给出结果。: O/ D1 K1 P3 o! Z m! P; A E
select product, sum(amount) as amount, case when count(*)=1 then min(ptype) else 'VAR' end as ptype, case when count(*)=1 then min(pdate) else null end as pdate from T group by product以下内容与您要求的不完全相同,但我认为它可能更接近您实际想要的内容。只有当多个不同的值组成聚合时,才会ptype报告为VAR或pdate报告为NULL。
5 P" K% }' W4 }- E- {8 w我加了一个pcount为了即使ptype和pdate都不为nulll,您仍然可以识别单重态集合。
1 h# j; [ C7 ], x3 @' ]select product, sum(amount) as amount, count(*) as pcount, case when count(distinct ptype)=1 then min(ptype) else 'VAR' end as ptype, case when count(distinct pdate)=1 then min(pdate) else null end as pdate from T group by product |
|
|
|
|
|