【问题标题】:How to insert additional values in between a GROUP BY如何在 GROUP BY 之间插入附加值
【发布时间】:2009-09-16 16:58:23
【问题描述】:

我目前正在使用 MySQL 制作月度报告。我有一个名为“monthly”的表,看起来像这样:

  id |         date        | amount

  10 | 2009-12-01 22:10:08 | 7 
  9  | 2009-11-01 22:10:08 | 78 
  8  | 2009-10-01 23:10:08 | 5 
  7  | 2009-07-01 21:10:08 | 54 
  6  | 2009-03-01 04:10:08 | 3 
  5  | 2009-02-01 09:10:08 | 456 
  4  | 2009-02-01 14:10:08 | 4 
  3  | 2009-01-01 20:10:08 | 20 
  2  | 2009-01-01 13:10:15 | 10 
  1  | 2008-12-01 10:10:10 | 5 

然后,当我制作月度报告(基于每年的每月)时,我会得到类似的结果。

年月 |总计

2008-12   | 5 
2009-01   | 30 
2009-02   | 460 
2009-03   | 3 
2009-07   | 54 
2009-10   | 5 
2009-11   | 78 
2009-12   | 7 

我用这个查询得到了结果:

SELECT substring(date, 1, 7) AS yearmonth, sum(amount) AS total 来自monthly GROUP BY 子字符串(日期, 1, 7)

但我需要这样的东西:

年月 |总计

2008-01   | 0 
2008-02   | 0 
2008-03   | 0 
2008-04   | 0 
2008-05   | 0 
2008-06   | 0 
2008-07   | 0 
2008-08   | 0 
2008-09   | 0
2008-10   | 0 
2008-11   | 0 
2008-12   | 5 
2009-01   | 30 
2009-02   | 460 
2009-03   | 3 
2009-05   | 0
2009-06   | 0
2009-07   | 54 
2009-08   | 0
2009-09   | 0
2009-10   | 5 
2009-11   | 78 
2009-12   | 7 

显示月份为零的东西,没有任何价值。甚至可以在 MySQL 查询中做到这一点吗?

【问题讨论】:

    标签: sql mysql


    【解决方案1】:

    您应该使用它生成一个虚拟行源和LEFT JOIN

    SELECT  *
    FROM    (
            SELECT  1 AS month
            UNION ALL
            SELECT  2
            … 
            UNION ALL
            SELECT  12 
            ) months
    CROSS JOIN
            (
            SELECT  2008 AS year
            UNION ALL
            SELECT  2009 AS year
            ) years
    LEFT JOIN
            mydata m
    ON      m.date >= CONCAT_WS('.', year, month, 1)
            AND m.date < CONCAT_WS('.', year, month, 1) + INTERVAL 1 MONTH
    GROUP BY
            year, month
    

    您可以将它们创建为磁盘上的表,而不是每次都生成它们。

    MySQL 是四大系统中唯一一个可以轻松生成任意结果集的系统。

    OracleSQL ServerPostgreSQL 确实有这些(分别为CONNECT BY、递归CTEgenerate_series

    【讨论】:

    • 所以唯一的办法就是创建一个新表?
    • @Marky: 或生成我的帖子中的值。新表更好。
    【解决方案2】:

    Quassnoi 是对的,我将添加一条评论,说明如何识别您何时需要这样的东西:

    您希望结果中包含“2008-01”,但源表中的任何内容都没有 2008 年 1 月的日期。结果集必须来自您查询的表,因此显而易见的结论是您需要一个额外的表- 包含您想要的每个月作为结果的一部分。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-02-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-05-25
      • 2012-03-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多