SQL按范围分组并保持为0

时间:2017-09-18 15:35:22

标签: mysql sql

我已经阅读了这个页面:In SQL, how can you "group by" in ranges?

响应帮助了我,但我有一个问题,如果范围的count()等于0,范围将不会显示,当count()等于0时,如何显示范围?

这是我的问题:

select 
    w.Période, 
    nb from( select t.Période, count(*) as nb 
from (select 
          *, 
          case 
              when report.creation_date between '2017-05-28 00:00:00' and '2017-06-25 00:00:00' 
                  then 'P3' 
              when report.creation_date between '2017-06-25 00:00:00' and '2017-07-23 00:00:00' 
                  then 'P4' 
              when report.creation_date between '2017-07-23 00:00:00' and '2017-08-20 00:00:00' 
                  then 'P5' 
              when report.creation_date between '2017-08-20 00:00:00' and '2017-09-17 00:00:00' 
                  then 'P6' 
              else 'Avant' 
          end as Période 
      from report 
      where report.office_id = 11) as t 
      group by t.Période ) as w

这是我的结果:

Avant 57
P3 1
P5 2
P6 4

我想:

Avant 57
P3 1
P4 0
P5 2
P6 4

我试过使用这些,但它不起作用。当count()为null时的情况则为0,否则count()以count()= 0结束为nb或case然后0 else count()以count()REGEXP'[^ [:digit:]]'结束为nb或case然后0,否则count()结束为nb

3 个答案:

答案 0 :(得分:2)

您应该针对派生表加入它们:

SELECT t.period,
       COALESCE(s.nb,0) as yourCount
FROM(SELECT 'P1' as period 
     UNION ALL 
     SELECT 'P2' 
     UNION ALL 
     ...) t -- This is the derived table
LEFT JOIN(Your Query Here) s -- This is your query
 ON(t.period = s.period)

答案 1 :(得分:0)

要稍微清理sagi提供的内容,您需要额外的膨胀和分组,但需要对输出中所需的所有合格期间进行预查询...这将是您要查询的主表。然后,从/ group by中选择一个简单的是LEFT-JOIN

select 
     preQuery.Période, 
     coalesce( PreSum.AllRecs, 0 ) as TotalRecs
   from
      ( select 'P3' as Période
        union all select 'P4'
        union all select 'P5'
        union all select 'P6'
        union all select 'Avant' ) preQuery
         LEFT JOIN
         ( select 
                 case when r.creation_date between '2017-05-28 00:00:00' 
                                               and '2017-06-25 00:00:00' 
                      then 'P3'
                      when r.creation_date between '2017-06-25 00:00:00'
                                               and '2017-07-23 00:00:00' 
                      then 'P4' 
                      when r.creation_date between '2017-07-23 00:00:00'
                                               and '2017-08-20 00:00:00' 
                      then 'P5' 
                      when r.creation_date between '2017-08-20 00:00:00'
                                               and '2017-09-17 00:00:00' 
                      then 'P6' 
                      else 'Avant' 
                 end as Période,
                 count(*) as AllRecs
            from 
               report r
            where 
               r.office_id = 11
            group by
                 case when r.creation_date between '2017-05-28 00:00:00' 
                                               and '2017-06-25 00:00:00' 
                      then 'P3'
                      when r.creation_date between '2017-06-25 00:00:00'
                                               and '2017-07-23 00:00:00' 
                      then 'P4' 
                      when r.creation_date between '2017-07-23 00:00:00'
                                               and '2017-08-20 00:00:00' 
                      then 'P5' 
                      when r.creation_date between '2017-08-20 00:00:00'
                                               and '2017-09-17 00:00:00' 
                      then 'P6' 
                      else 'Avant' end ) PreSum
             on PreQuery.Période = PreSum.Période

答案 2 :(得分:0)

如果你有表格中的值,但不是那个办公室,你可以这样做:

  select (case when r.creation_date between '2017-05-28' and '2017-06-25' 
               then 'P3' 
               when r.creation_date between '2017-06-25' and '2017-07-23' 
               then 'P4' 
               when r.creation_date between '2017-07-23' and '2017-08-20' 
               then 'P5' 
               when r.creation_date between '2017-08-20' and '2017-09-17' 
               then 'P6' 
               else 'Avant' 
           end) as Période ,
          sum(r.office_id = 11) as cnt
  from report r
  group by Période;

条件聚合方法通常比使用外连接更容易实现。在您明确选择所需行的意义上,外连接更通用。这种方法更为通用,即数据中的任何句点都将被表示 - 即使它是一个新句点。

一些注意事项:

  • 不需要这么多子查询。这只会使优化器的工作更难以完成,人类更难以遵循查询。
  • 我是合格列名的忠实粉丝(查询中的r.)。
  • 在指定日期时,您不需要包含00:00:00

事实上,更清晰的逻辑是:

如果你有表格中的值,但不是那个办公室,你可以这样做:

  select (case when r.creation_date < '2017-06-26' 
               then 'P3' 
               when r.creation_date < '2017-07-24' 
               then 'P4' 
               when r.creation_date < '2017-08-21' 
               then 'P5' 
               when r.creation_date < '2017-09-18' 
               then 'P6' 
               else 'Avant' 
           end) as Période ,
          sum(r.office_id = 11) as cnt
  from report r
  where r.creation_date >= '2017-05-28'
  group by Période;

请注意,使用了不等式<。这很方便,因为它可以同时适用于日期和日期/时间。