问题描述
|
我有一张桌子,看起来像
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月份没有任何行,那么7月份将不会显示。
如何强制7月显示其值为0?
解决方法
没有简单的方法可以做到这一点。一种可能的方法是拥有一个称为months的表:
其中将有12行:(1月,2月,...,12月)
您可以将Months表与必须获得所需输出的查询结合起来。
, 普遍的共识是,您应该只创建一个月份名称表。接下来是一个愚蠢的解决方案,可以作为一种解决方法。
您必须自己处理细节,但是您是否在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)
疯了,不是吗?
, MySQL没有递归功能,因此您只能使用NUMBERS
表技巧-
创建仅包含递增数字的表-使用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;
使用以下命令填充表:
INSERT INTO NUMBERS
(id)
VALUES
(NULL)
...根据需要提供尽可能多的值。在这种情况下,INSERT语句至少需要运行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
使用OUTER JOIN获得所需的输出:
SELECT x.dt,COUNT(*) AS total
FROM (SELECT 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
为什么是数字而不是日期?
简单-可以根据数字生成日期,就像我提供的示例一样。这也意味着只使用一个表,而不是每个数据类型一个表。
, select MONTHNAME(expires) as month_name,sum(`value`) from Table1
group by month_name order by null;
小提琴