3

我有一张看起来像的桌子

expires    | value  
-------------------
2011-06-15 | 15  
2011-06-15 | 15  
2011-06-25 | 15  
2011-07-15 | 15  
2011-07-15 | 15  
2011-07-25 | 15  
2011-08-15 | 15  
2011-08-15 | 15  
2011-08-25 | 15

我想运行一个会吐出的查询

June   | 45  
July   | 45  
August | 45  

所以我的查询是

  SELECT SUM(amount) AS `amount`, 
         DATE_FORMAT(expires , '%M') AS `month`  
    FROM dealDollars 
   WHERE DATE(expires) BETWEEN DATE(NOW()) 
                           AND LAST_DAY(DATE(NOW()+INTERVAL 3 MONTH)) 
GROUP BY MONTH(expires)

哪个工作正常。但是结果,如果说七月没有行,七月就不会出现。

如何强制 7 月显示为 0 作为其值?

4

4 回答 4

4

没有简单的方法可以做到这一点。一种可能的方法是有一个名为months的表:它将有12行:(一月,二月,...,十二月)

您可以将 Months 表与您必须获得所需输出的查询一起加入。

于 2011-06-15T03:36:04.587 回答
1

MySQL 没有递归功能,因此您只能使用NUMBERS表格技巧 -

  1. 创建一个只包含递增数字的表 - 使用 auto_increment 很容易做到:

    DROP TABLE IF EXISTS `example`.`numbers`;
    CREATE TABLE  `example`.`numbers` (
      `id` int(10) unsigned NOT NULL auto_increment,
       PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
    
  2. 使用以下方法填充表:

    INSERT INTO NUMBERS
      (id)
    VALUES
      (NULL)
    

    ...根据需要获取尽可能多的值。在这种情况下,INSERT 语句至少需要运行 3 次。

  3. 使用DATE_ADD构造天数列表,根据NUMBERS.id值增加:

    SELECT x.dt
      FROM (SELECT DATE(DATE_SUB(CURRENT_DATE(), INTERVAL (n.id - 1) MONTH)) AS dt
              FROM numbers n
             WHERE DATE(DATE_SUB(CURRENT_DATE(), INTERVAL (n.id - 1) MONTH)) BETWEEN CURRENT_DATE()
                                                                                 AND LAST_DAY(CURRENT_DATE() +INTERVAL 3 MONTH))  ) x
    
  4. 使用 OUTER JOIN 获得所需的输出:

       SELECT x.dt,
              COUNT(*) AS total
         FROM (SELECT DATE(DATE_SUB(CURRENT_DATE(), INTERVAL (n.id - 1) MONTH)) AS dt
              FROM numbers n
             WHERE DATE(DATE_SUB(CURRENT_DATE(), INTERVAL (n.id - 1) MONTH)) BETWEEN CURRENT_DATE()
                                                                                 AND LAST_DAY(CURRENT_DATE() +INTERVAL 3 MONTH))  ) x
    LEFT JOIN YOUR_TABLE y ON y.date = x.dt
     GROUP BY x.dt
     ORDER BY x.dt
    

为什么是数字,而不是日期?

简单 - 可以根据数字生成日期,就像我提供的示例一样。这也意味着使用一个表,而不是每个数据类型一个表。

于 2011-06-15T05:02:10.047 回答
1

一般的共识是您应该只创建一个月份名称表。接下来是一个愚蠢的解决方案,可以作为一种解决方法。

您必须自己处理细节,但是您是否查看过 from 子句中的子查询

基本上,它会是这样的:

SELECT NVL(B.amount, 0) as `amount`, A.month as `month`
      FROM (SELECT 'January' as `month`
            UNION SELECT 'February' as `month`
            UNION SELECT 'March' as `month`...
            UNION SELECT 'DECEMBER' as `month`) as A
      LEFT JOIN
            (SELECT SUM(amount) AS `amount`, 
                    DATE_FORMAT(expires , '%M') AS `month`  
               FROM dealDollars 
               WHERE 
                  DATE(expires) BETWEEN 
                       DATE(NOW()) AND 
                       LAST_DAY(DATE(NOW()+INTERVAL 3 MONTH)) 
               GROUP BY MONTH(expires)) as B
            ON (A.MONTH = B.MONTH)

疯了吧?

于 2011-06-15T03:47:36.770 回答
0
select MONTHNAME(expires) as month_name,sum(`value`) from Table1
group by month_name order by null;

小提琴

于 2013-07-29T05:25:03.737 回答