填补月份差距

时间:2012-07-28 08:51:48

标签: mysql database date

如果一个月内没有订单,我需要填0。

表示例:

date         product
2010-02-01   20 
2010-03-01   10
2010-03-01   30
2010-06-01   15

我的基本查询是:

SELECT date,SUM(orders.product) AS product
FROM orders 
GROUP BY month(date),YEAR(date)

那会回来:

date         product
2010-02-01   20 
2010-03-01   40
2010-06-01   15

但我需要:

date         product
2010-02-01   20 
2010-03-01   40
2010-04-01   0
2010-05-01   0
2010-06-01   15

我制作了一张包含所有可能日期的表格:

datefield
2010-01-01  
2010-02-01  
2010-03-01 
2010-04-01  
2010-05-01  
2010-06-01  
2010-07-01  
etc...

但是当我尝试加入这两个时它不起作用。 (编辑:仅适用于第一个缺失的月份。)

SELECT calendar.datefield AS DATE,
IFNULL(SUM(orders.product),0) AS product
FROM orders RIGHT JOIN calendar ON (MONTH(orders.date) = MONTH(calendar.datefield)) AND (YEAR(orders.date) = YEAR(calendar.datefield)) 
WHERE (calendar.datefield BETWEEN (SELECT MIN(DATE(date)) FROM orders) AND (SELECT MAX(DATE(date)) FROM orders))
GROUP BY DATE 

4 个答案:

答案 0 :(得分:2)

ON (DATE(orders.date) = calendar.datefield) 

您要从orders.date中提取年/月/日,但不从日期字段中提取。可能是那样。

我会尝试

ON (DATE(orders.date) = DATE(calendar.datefield))

另外,如你想要几个月,我只会按月检查

ON (MONTH(orders.date) = MONTH(calendar.datefield)) AND (YEAR(orders.date) = YEAR(calendar.datefield)) 

现在你只需要一个月的行,而不是每天一行。

答案 1 :(得分:1)

您需要联合日历表。

SELECT date,SUM(orders.product) AS product
FROM orders 
GROUP BY month(date),YEAR(date)
union
select datefield AS date, '0' AS product
from calendar

答案 2 :(得分:0)

这解决了我的问题:

SELECT date, product FROM (
SELECT date,SUM(orders.product) AS product
FROM orders 
GROUP BY MONTH(date),YEAR(date)
UNION 
select datefield AS date, '0' AS product
from calendar
WHERE (calendar.datefield BETWEEN (SELECT MIN(DATE(date)) FROM orders) AND (SELECT MAX(DATE(date)) FROM orders))
GROUP BY MONTH(date),YEAR(date)
) AS a
GROUP BY MONTH(date),YEAR(date)
ORDER BY date

答案 3 :(得分:0)

在我的日历表中,日期保存在“cal_date”列中。语法适用于PostgreSQL;它应该很容易适应MySQL。

select to_char(cal_date, 'YYYY-MM') as period, sum(coalesce(product, 0))
from orders 
right join calendar c on c.cal_date = orders.date
where (
  cal_date >= (select min(date) from orders) and
  cal_date <= (select max(date) from orders)
)
group by period
order by period

to_char(cal_date, 'YYYY-MM') as period返回名为“period”的列,其中包含“2010-02”之类的值。当我按月汇总时,我不想回复约会。它往往会让人感到困惑。

正确的加入应该基于日期值,而不是仅仅基于月份和年份。 (想一想。)

如果您感兴趣的范围中的第一个月或最后一个月没有订单,则WHERE子句会出错。基于传递的参数而不是实际订单的范围可能是一个更好的主意。