【问题标题】:Handle unobserved categories when group by SQL按 SQL 分组时处理未观察到的类别
【发布时间】:2018-06-09 20:54:36
【问题描述】:

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

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

但我想得到的其实是这个

Month   sum
Jan.    5
Feb.    0
Mar.    5
Apr.    3
May.    0
June.   0
July.   1
Aug.    0
Sept.   4
Oct.    0
Nov.    15
Dec.    12

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

我该怎么做?

谢谢。

【问题讨论】:

  • 你的 dbms 是什么?

标签: sql group-by missing-data


【解决方案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

【讨论】:

    【解决方案2】:

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

    创建一个月份表(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
    

    您当然可以使用月份名称代替月份编号,或者使用特定于您的数据库的函数将月份编号转换为名称。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-20
      • 2020-02-27
      • 2016-04-28
      • 1970-01-01
      相关资源
      最近更新 更多