sql - 高效使用SQL GROUP BY、SUM、COUNT

标签 sql performance count group-by sum

我有一张产品销售表,可能如下所示:

product   | amount   | ptype    | pdate      
p1        | 1.00     | sale     | 01/01
p1        | 2.00     | base     | 01/02
p2        | 1.50     | sale     | 02/03
p3        | 5.25     | base     | 10/10

我想建立一个表格,每行显示一个产品,金额的总和,如果产品是唯一的,则显示类型,否则将类型显示为“VAR”,如果产品是唯一的,则显示日期,否则显示日期作为 NULL。结果如下所示:
product   | total    | ptype    | pdate      
p1        | 3.00     | VAR      | (NULL)
p2        | 1.50     | sale     | 02/03
p3        | 5.25     | base     | 10/10

我通过执行以下操作来完成我需要的结果:
SELECT 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 pdate
FROM T as a

但我想知道是否有更有效的方法来实现相同的结果。

最佳答案

无需使用任何形式的子查询或内联 View 。根据数据库引擎的复杂程度,这些构造可能会对性能产生负面影响。

这是您所要求的,即使在最原始的 SQL 引擎上,它也应该通过对表的单次扫描来可靠地给出结果。

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。

我添加了一个 pcount 列,以便您仍然可以识别单线聚合,即使 ptype 和 pdate 都不为空。
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

关于sql - 高效使用SQL GROUP BY、SUM、COUNT,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11255938/

相关文章:

Mysql 减去 'N' 天日期值并与当前日期进行比较。 N 和 Date 是两个列值

python - 澄清 pstats 模块的输出

php - 检查记录是否存在的最简洁方法

sql - 计算每个唯一值的出现次数

关于评论投票的mysql子查询问题

java - 将 JSP 表中的更改保存到数据库中

sql - 如何在SQL查询中处理Excel文件?

sql - 获取之前的分数

javascript - 2 AngularJS 图像获取中单个资源的 GET 方法形成

java - Android 中的暂停和恢复线程。工作室