【发布时间】:2012-05-18 18:12:26
【问题描述】:
我正在尝试优化 SQL 查询以使我的报告看起来更好。我的查询从一个表中读取数据,按几列分组并计算一些聚合字段(计数和总和)。
SELECT A, B, C, COUNT(*), SUM(D) FROM T
GROUP BY A, B, C
ORDER BY A, B, C
现在,假设 B 和 C 列是一些已定义的常量字符串,例如,
B 可以是'B1' 或'B2',C 可以是'C1' 或'C2'。因此,一个示例结果集是:
A | B | C | COUNT(*) | SUM(D)
--------------------------------
A1 | B1 | C1 | 34 | 1752
A1 | B1 | C2 | 4 | 183
A1 | B2 | C1 | 199 | 8926
A1 | B2 | C2 | 56 | 2511
A2 | B1 | C2 | 6 | 89
A2 | B2 | C2 | 12 | 231
A3 | B1 | C1 | 89 | 552
...
如您所见,对于'A1',我有所有四种可能的(B,C)组合,但对于'A2',情况并非如此。我的问题是:实际上,在给定的表中,如何生成不存在 (B, C) 组合的摘要行?也就是说,我怎样才能打印,例如,这些行:
A | B | C | COUNT(*) | SUM(D)
--------------------------------
A2 | B1 | C1 | 0 | 0
A2 | B2 | C1 | 0 | 0
我能看到的唯一解决方案是创建一些具有所有 (B, C) 值的辅助表,然后使用该辅助表进行 RIGHT OUTER JOIN。但我正在寻找一种更清洁的方式......
谢谢大家。
【问题讨论】:
-
你用的是什么mssql、oracle、mysql?
-
甲骨文。但目前,查询是以标准方式编写的(它也在 MySQL 上运行,我们有一个数据库的 MySQL 副本,没有与问题相关的原因)。
-
也许this 有帮助。分组集在 SQL Server 和 Oracle 中都可用。不确定 MySQL。
-
@dradu 非常有趣。我以前从未听说过 CUBE 和 GROUPING SETS。也许是因为我主要是 MySQL 用户。无论如何,它无济于事:CUBE 和 GROUPING SETS 都生成任何类型的总计,但不会生成空摘要。
-
什么是使用右外连接解决问题的“不干净”?这似乎是正确的解决方案。
标签: sql oracle group-by aggregate-functions