您需要一个为维度中所有月份提供值的行源,然后将您的 yearly_sales 表加入其中。
您正在执行 GROUP BY,您很可能想要对您的度量进行聚合 (sales_amount_sold),或者您不想要 GROUP BY。(您问题中的查询将在给定月份中仅针对一行从 sales_amount_sold 返回一个值。这可能是您想要的,但返回的结果集非常奇怪。)
一种方法是创建一个“calendar_month”表,其中包含您想要返回的所有月份的 DATE 值。(还有其他方法可以生成这个,stackoverflow 上其他地方的问题的现有答案)
SELECT m.month AS sale_date
, IFNULL(SUM(s.sales_amount_sold),0) AS sale_amt
FROM calendar_months m
LEFT
JOIN yearly_sales s
ON s.sales_date_sold >= m.month
AND s.sales_date_sold < DATE_ADD(m.month,INTERVAL 1 MONTH)
WHERE m.month BETWEEN DATE_SUB(SYSDATE(), INTERVAL 2 YEAR) AND SYSDATE()
GROUP BY m.month
ORDER BY m.month
此查询返回的结果略有不同,您只会获取“整月”组中的行,而不是像原始查询中那样包括部分月份,因为 sale_date 上的 WHERE 子句引用当前日期和时间前两年,而不是两年前的“月初”。
不一定需要 calendar_months 表;这可以替换为返回行源的查询。在这种情况下,可以将月份值的谓词从外部查询移动到子查询中。
附录:如果您使用 calendar_month 表作为行源,则需要使用您想要返回的每个可能的“月”值填充它。
CREATE TABLE calendar_month
(`month` DATE NOT NULL PRIMARY KEY COMMENT 'one row for first day of each month');
INSERT INTO calendar_month(`month`) VALUES ('2011-01-01'),('2011-02-01'),('2011-03-01')
作为替代方案,您可以将动态生成的行源指定为内联视图,而不是表引用。(您可以使用类似的查询来快速填充 calendar_months 表。)
您可以将此查询包装在括号中,并将其粘贴FROM
在calendar_months
我提供的上一个查询之间。
SELECT DATE_ADD('1990-01-01',INTERVAL 1000*thousands.digit + 100*hundreds.digit + 10*tens.digit + ones.digit MONTH) AS `month`
FROM ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) ones
JOIN ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) tens
JOIN ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) hundreds
JOIN ( SELECT 0 AS digit UNION ALL SELECT 1 UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5 UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 ) thousands