0

如果一个月内没有订单,我需要用 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

4 回答 4

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)) 

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

于 2012-07-28T08:57:12.047 回答
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
于 2012-07-28T10:05:08.087 回答
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
于 2012-07-28T11:10:34.327 回答
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 子句将出现异常。基于传递的参数而不是实际订单的范围可能是一个更好的主意。

于 2012-07-28T12:04:35.080 回答