回答

收藏

高效使用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
分享到:
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则