SQL:从同一个表中聚合不同的月份

Posted

技术标签:

【中文标题】SQL:从同一个表中聚合不同的月份【英文标题】:SQL: Aggregate different months from same table 【发布时间】:2015-04-15 10:06:49 【问题描述】:

假设我有一张表格,其中包含产品日期的销售情况。唉,我不能在这里格式化表格,因此作为代码:

table1:

Product|Date|Sales
-------|----|-----
ProdA  |1.1.|100
ProdB  |1.1.| 50
ProdC  |1.1.| 75
ProdA  |2.1.|110
ProdB  |2.1.| 60
ProdC  |2.1.| 60
....   |... |...

我需要一个包含每个月销售额的新表:

Product| Jan| Feb|...
-------|----|----|...
ProdA  |1234|1400|...
ProdB  | 234| 400|...
ProdC  | 524| 640|...
...    |... |... |...

我尝试使用带有CASE 的SQL 查询。 [] 中的文字是缩写,真正的表达式是有效的to_char(to_month(..)) construct

SELECT 
    Product,
    CASE WHEN [date == 1] THEN SUM(Sales) END AS Jan,
    CASE WHEN [date == 2] THEN SUM(Sales) END AS Feb,
    CASE WHEN [date == 3] THEN SUM(Sales) END AS Mar,
    ...
FROM
    table1
GROUP BY
    Product

我收到了00979. 00000 - "not a GROUP BY expression" 错误。

我知道我可以通过为每个月构建表并再次添加一些表来解决问题,但这会降低性能。我也想明白,为什么构造不起作用?

PS: - [Edit1]:它是一个 Oracle 数据库

【问题讨论】:

您使用的是哪个 DBMS?后格雷斯?甲骨文? to_char(to_month(..)) - 我不确定我是否理解这一点。 Oracle 没有to_month() 函数。无论如何,最好将日期视为日期。 我只是简写了那个,因为它不相关,但删掉的表达式是:to_Number(to_char(date,'MM'))=2。日期字段确实是一个日期。我想,有更好的方法,但那行得通。 【参考方案1】:

尝试在case声明sum(case when end)之前给出agreegation

SELECT 
    Product,
    sum(CASE WHEN date = 1 THEN Sales END) AS Jan,
    SUM(CASE WHEN date = 2 THEN Sales END) AS Feb,
    SUM(CASE WHEN date = 3 THEN Sales END) AS Mar,
    ...
FROM
    table1
GROUP BY
    Product

【讨论】:

至少,这不会引发错误。第一次测试显示了正确的数据。有什么不同?为什么会这样? 您在 case 语句中同意数据,因此它不会将其视为完整的同意数据。这就是为什么它不按表达式显示分组

以上是关于SQL:从同一个表中聚合不同的月份的主要内容,如果未能解决你的问题,请参考以下文章

如何从 sql 中的 2 个表中按组聚合和计算平均值?

从结合 SQL 组的 JSONB 数组中聚合不同的值

不同的聚合函数取决于数据类型

基于 ID 聚合记录的 SQL 查询

可以在一个交叉应用中使用两个聚合吗?

MySQL聚合函数