【问题标题】:MySQL Count per Quarter per Year, with 0 count每年每季度的 MySQL 计数,计数为 0
【发布时间】:2016-01-09 15:50:29
【问题描述】:

我有一张带行李的桌子,上面有柱子:

status(VARCHAR) - (“丢失”、“找到”等)

datefound(DATE) - (YYYY-MM-DD)


我的行李桌:

   -------------------------------------------
  | status | otherattributes |   datefound    |
   -------------------------------------------
  | lost   | ............... |   2014-11-17   |
  | found  | ............... |   2015-05-28   |
  | lost   | ............... |   2016-11-17   |
  | lost   | ............... |   2015-10-20   |
                     etc..

我想每年每季度统计一张表中状态为“丢失”的行李件。 同时还返回没有“丢失”件的宿舍(计数 = 0)。

我想要什么:

所需的表格如下所示:

   ------------------------------
  | year | quarter | amountlost |
   ------------------------------
  | 2014 |    1    |     23     |
  | 2014 |    2    |     41     |
  | 2014 |    3    |      0     |
  | 2014 |    4    |     12     |
  | 2015 |    1    |     32     |
  | 2015 |    2    |      0     |
  | 2015 |    3    |      9     |
  | 2015 |    4    |     27     |
  | 2016 |    1    |     53     |
  | 2016 |    2    |     24     |
  | 2016 |    3    |     11     |
  | 2016 |    4    |      0     |
   ------------------------------

我现在拥有的:

我目前有一个查询,但它不返回 COUNT 为 0 的年 + 季度。我尝试使用临时表,但我无法让它工作..

我正在处理的当前查询:

(没有给出想要的结果)

SELECT YEAR(datefound) AS year, QUARTER(datefound) AS quarter, COUNT(status) AS amountlost FROM luggage WHERE status = 'lost' GROUP BY YEAR(datefound), QUARTER(datefound) ORDER BY YEAR(datefound), QUARTER(datefound)

导致(不需要):

   ------------------------------
  | year | quarter | amountlost |
   ------------------------------
  | 2014 |    4    |     10     |
  | 2015 |    1    |     32     |
  | 2015 |    2    |      0     |
  | 2015 |    3    |      9     |
  | 2015 |    4    |     27     |
  | 2016 |    1    |     53     |
   ------------------------------

在结果表上方缺少 2014 年和 2016 年的季度,这将导致计数为 0 @amountlost。

希望有人可以帮助我查询(可能是临时表?),为我提供所需的表!

【问题讨论】:

    标签: mysql sql date temp-tables


    【解决方案1】:

    在这种情况下,您有两个选择。更容易的是当您的输入数据包含所有年份和季度,但 where 子句将它们过滤掉时。然后你可以切换到条件聚合:

    SELECT YEAR(datefound) AS year, 
           QUARTER(datefound) AS quarter, 
           SUM(status = 'lost') AS amountlost
    FROM luggage
    GROUP BY YEAR(datefound), QUARTER(datefound)
    ORDER BY YEAR(datefound), QUARTER(datefound);
    

    如果这不起作用,那么您需要生成可能的行,然后添加附加信息。假设数据中有每一年和每一季度的代表:

    SELECT y.yyyy, q.qq, COUNT(l.status) as AmountLost
    FROM (SELECT DISTINCT YEAR(datefound) as yyyy FROM luggage) y CROSS JOIN
         (SELECT DISTINCT QUARTER(datefound) as qq FROM LUGGAGE) q LEFT JOIN
         luggage l
         ON YEAR(l.datefound) = y.yyyy AND QUARTER(l.datefound) = q.qq AND
            l.status = 'lost'
    GROUP BY y.yyyy, q.qq;
    

    如果您的数据在这方面甚至不完整,那么您需要生成所需的行。比如:

    SELECT yq.yyyy, yq.qq, COUNT(l.status) as AmountLost
    FROM (SELECT 2014 as yyyy, 1 as qq  UNION ALL
          SELECT 2014, 2 UNION ALL
          . . .
         ) yq LEFT JOIN
         luggage l
         ON YEAR(l.datefound) = yq.yyyy AND QUARTER(l.datefound) = yq.qq AND
            l.status = 'lost'
    GROUP BY yq.yyyy, yq.qq;
    

    注意:您可能已经有一个表格,其中包含报告的适当年份和季度。如果是这样,您可以使用它。如果你有某种数字表,也可以使用(加上一些额外的逻辑)。

    【讨论】:

    • 第二个创造了奇迹,非常感谢!我将其稍微更改为仅计算 status = 'lost' ,而不是计算所有状态。 ---------------- SELECT y.yyyy, q.qq, coalesce(SUM(status = 'lost'), 0) as Amountlost FROM (SELECT DISTINCT YEAR(datefound) as yyyy FROM luggage) y CROSS JOIN (SELECT DISTINCT QUARTER(datefound) as qq FROM LUGGAGE) q LEFT JOIN luggage l ON YEAR(l.datefound) = y.yyyy AND QUARTER(l.datefound) = q.qq GROUP BY y.yyyy, q.qq; ------- coalesce(SUM(status = 'lost'), 0) as Amountlost 而不是COUNT(l.status) as AmountLost
    猜你喜欢
    • 1970-01-01
    • 2020-01-20
    • 1970-01-01
    • 1970-01-01
    • 2021-11-18
    • 1970-01-01
    • 1970-01-01
    • 2021-12-20
    • 1970-01-01
    相关资源
    最近更新 更多