MySQL:选择两个日期之间的所有数据

44

我有一个MySQL表格,其中包含与日期相关的数据。每行都有数据和日期,就像这样:

2009-06-25    75
2009-07-01    100
2009-07-02    120

我有一个MySQL查询,可以选择两个日期之间的全部数据。这是该查询:

SELECT data FROM tbl WHERE date BETWEEN date1 AND date2

我的问题是,我需要获得在date1和date2之间的行,即使一天没有数据。

所以我的查询会忽略2009-06-25和2009-07-01之间没有数据的日期。

我是否可以通过某种方式添加这些日期,并将数据设为0?

7个回答

38

你可以使用一个常被称为“日历表”的概念。 这里是一个很好的关于如何在MySQL中创建日历表的指南:

-- create some infrastructure
CREATE TABLE ints (i INTEGER);
INSERT INTO ints VALUES (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);

-- only works for 100 days, add more ints joins for more
SELECT cal.date, tbl.data
FROM (
    SELECT '2009-06-25' + INTERVAL a.i * 10 + b.i DAY as date
    FROM ints a JOIN ints b
    ORDER BY a.i * 10 + b.i
) cal LEFT JOIN tbl ON cal.date = tbl.date
WHERE cal.date BETWEEN '2009-06-25' AND '2009-07-01';

您可能希望创建表cal,而不是使用子查询。


Josef:我想你的意思是 http://www.artfulsoftware.com/infotree/queries.php?&bw=1504#95 - feihtthief
4
这些网址完全相同,对吧? - Josef Pfleger

12
Select *  from  emp where joindate between date1 and date2;

但是这个查询并没有展示正确的数据。

例如

1-jan-2013 to 12-jan-2013.

但这是展示数据

1-jan-2013 to 11-jan-2013.

2
我使用了这个方法,因为我的日期字段是DATETIME类型的,所以像这样输入某一天内的数据范围值时 'BETWEEN'2013-10-12 00:00:00'and'2013-10-12 23:59:59' 是准确的!非常感谢您。 - ipruthi
1
@gulab,你可以使用 SELECT * FROM emp WHERE DATE(joindate) BETWEEN date1 AND date2; - shweta

10

处理这种情况非常容易。

您可以使用BETWEEN CLAUSEdate_sub(now(), INTERVAL 30 DAY) AND NOW()结合使用。

SELECT
    sc_cust_design.design_id as id,
    sc_cust_design.main_image,
    FROM
    sc_cust_design
WHERE
    sc_cust_design.publish = 1 
    AND **`datein`BETWEEN date_sub( now( ) , INTERVAL 30 DAY ) AND NOW( )**

编程愉快 :)


4

您是否有一个包含所有日期的表格?如果没有,您可能需要考虑实现一个日历表格,并将您的数据左连接到日历表格上。


1
如果可以避免的话,请不要这样做。
数据库并没有为此而设计,您实际上正在尝试在查询中创建数据(尽管是一组日期)。
对于任何具有数据库查询上面的应用程序层的人来说,最简单的解决方案是在那里填写空白数据。
您很可能会循环遍历查询结果,并且可以实现类似以下内容的东西:
loop_date = start_date

while (loop_date <= end_date){

  if(loop_date in db_data) {
    output db_data for loop_date
  }
  else {
    output default_data for loop_date
  }

  loop_date = loop_date + 1 day
}

这样做的好处是减少数据传输;查询更简单、易于调试;而且不必担心日历表溢出。

1

您需要使用以下代码将结束日期增加1天: DATE_ADD('$end_date', INTERVAL 1 DAY)


这并没有回答 OP 的问题——即使某一天没有数据,也要获取日期1和日期2之间的行。 - Uwe

-1

您可以使用一个替代方案:

SELECT * FROM TABLE_NAME WHERE `date` >= '1-jan-2013' 
OR `date` <= '12-jan-2013'

在发布之前,您是否尝试过您的代码?使用“OR”会有误,因为它会返回所有行。但是,即使将“OR”替换为“AND”,这也无法回答OP的问题-获取日期1和日期2之间的行,即使某一天没有数据。 - Uwe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接