0

一段时间以来一直在尝试解决这个问题。我真的很感激任何帮助。

我有这张表,其中我得到了 2 列,分别带有日期和 int 值。问题是 mysql 在 int 值为空的地方跳过日期值。

这里是sql语句

SELECT DATE_FORMAT(sales_date_sold, '%b \'%y')
    AS sale_date, sales_amount_sold 
    AS sale_amt 
    FROM yearly_sales 
    WHERE sales_date_sold BETWEEN DATE_SUB(SYSDATE(), INTERVAL 2 YEAR) AND SYSDATE() 
    GROUP BY YEAR(sales_date_sold), MONTH(sales_date_sold) 
    ORDER BY YEAR(sales_date_sold), MONTH(sales_date_sold) ASC;

2011 年 2 月没有任何值,因此会跳过该月以及其他一些月。合并和 if_null 也不起作用。

4

4 回答 4

1

您需要一个为维度中所有月份提供值的行源,然后将您的 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 表。)

您可以将此查询包装在括号中,并将其粘贴FROMcalendar_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
于 2012-06-26T18:00:45.750 回答
1

问题不在于该值为 NULL,而在于您正在从数据库中选择数据。如果您没有特定月份的数据,MySQL 将无法选择不存在的数据。

在 MySQL 中完全解决这个问题的唯一方法已经在一个非常相似的问题中得到了回答

于 2012-06-26T18:01:14.307 回答
0

我以前遇到过时间戳问题。我使用的解决方案是创建一个包含所有月份的参考表。这可能是一张只有数字 1-12(12 行)的表格,或者您可以更进一步并输入月份名称。然后你就可以离开加入你yearly_sales1_through_12表来获取每个月的表。

于 2012-06-26T18:00:24.980 回答
0

为什么不直接使用 0 而不是 NULL?

于 2012-06-26T18:02:40.420 回答