按SQL分组处理未观察到的类别

时间:2018-06-09 20:54:37

标签: sql group-by missing-data

我有一个关于在分组时处理未观察到的类别的问题。 例如,

use Symfony\Component\Routing\Annotation\Route;

如果我使用此查询

Month   Number
Jan.    1
Jan.    4
Mar.    5
Apr.    3
July.   1
Sept.   4
Nov.    7
Nov.    8
Dec.    9
Dec.    1
Dec.    2

它只会返回一个像这样的表

select t.Month, sum(t.Number) as sum from table t group by t.Month;

但我想得的实际上就是这个

Month   sum
Jan.    5
Mar.    5
Apr.    3
July.   1
Sept.   4
Nov.    15
Dec.    12

它还将包括那些未观察到的月份并将值返回为0。

我怎么能这样做?

谢谢。

2 个答案:

答案 0 :(得分:1)

您需要LEFT JOIN日历,按日历按月分组。

select cd.months, coalesce(sum(t.Number),0) as 'sum' 
from (
SELECT 'Jan.' as 'months' UNION ALL
SELECT 'Feb.' UNION ALL
SELECT 'Mar.' UNION ALL
SELECT 'Apr.' UNION ALL
SELECT 'May.' UNION ALL
SELECT 'June.' UNION ALL
SELECT 'July.' UNION ALL
SELECT 'Aug.' UNION ALL
SELECT 'Sept.' UNION ALL
SELECT 'Oct.' UNION ALL
SELECT 'Nov.' UNION ALL
SELECT 'Dec.' 
) cd LEFT JOIN T on cd.months = t.Month
group by cd.months;

sqlfiddle:https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=1aca12dbcc087ce85145e3a8919a6182

答案 1 :(得分:0)

使用left outer join,其中左侧是所有月份的表格,右侧是与每个月相关联的值表格。这是一个例子:

创建一个月份表(1代表1月 - 如果更容易,你也可以坚持使用月份名称):

create table month (month int);
insert into month values
    (1), (2), (3), (4), (5), (6), (7), (8), (9), (10), (11), (12);

与每个月相关的可汇总值表:

create table month_val (month int, val int);
insert into month_val values
    (1, 10), (1, 11), (2, 20), (2, 21), (3, 30);

左连接表:

select month.month, coalesce(sum(month_val.val), 0)
from month
left join month_val on (month.month = month_val.month)
group by month.month

结果:

month   coalesce(sum(month_val.val), 0)
1   21
2   41
3   30
4   0
5   0
6   0
7   0
8   0
9   0
10  0
11  0
12  0

您当然可以使用月份名称而不是月份号码,或使用特定于您的数据库的函数将月份号码转换为名称。