mysql跳过某些月份

时间:2012-06-26 17:55:29

标签: mysql

试图将这个问题排序一段时间。我真的很感激任何帮助。

我有这个表,我分别得到2列有date和int值的列。问题是mysql在int值为null的地方跳过日期值。

这里是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年的feb没有任何值,因此月份会被跳过,还会有其他几个。 Coalesce和if_null也不起作用。

4 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

在MySQL中完全解决这个问题的唯一方法是already answered in a very similar question

答案 2 :(得分:0)

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

答案 3 :(得分:0)

为什么不用0而不是NULL?