MySQL:查找日期范围之间的缺失日期

Lax*_*idi 3 mysql date gaps-and-islands

我需要一些mysql查询的帮助.我有从2011年1月1日到2011年4月30日的数据的数据库表.应该有每个日期的记录.我需要找出表中是否缺少任何日期.

例如,假设2011年2月2日没有数据.我如何找到该日期?

我将日期存储在名为reportdatetime的列中.日期存储格式为:2011-05-10 0:00:00,即2011年5月5日上午12:00:00.

有什么建议?

Bil*_*win 7

这是第二个答案,我将单独发布.

SELECT DATE(r1.reportdate) + INTERVAL 1 DAY AS missing_date
FROM Reports r1
LEFT OUTER JOIN Reports r2 ON DATE(r1.reportdate) = DATE(r2.reportdate) - INTERVAL 1 DAY
WHERE r1.reportdate BETWEEN '2011-01-01' AND '2011-04-30' AND r2.reportdate IS NULL;
Run Code Online (Sandbox Code Playgroud)

这是一个自联接,它报告日期,使得下一个日期不存在任何行.

这将在缺口中找到第一天,但​​如果缺少多天的运行,则不会报告缺口中的所有日期.

  • 稍微修改它以解决导致自连接变得疯狂的重复日期值:`SELECT DISTINCT DATE(r1.date) + INTERVAL 1 DAY AS missing_date FROM mytable r1 LEFT OUTER JOIN (SELECT DISTINCT date FROM mytable) r2 ON DATE( r1.date) = DATE(r2.date) - 间隔 1 天,其中 r1.date 介于 '2011-06-19' 和 '2012-08-30' 并且 r2.date 为 NULL` (2认同)

Bil*_*win 5

  1. CREATE TABLE Days (day DATE PRIMARY KEY);

  2. 填写Days您正在寻找的所有日子.

    mysql> INSERT INTO Days VALUES ('2011-01-01');
    mysql> SET @offset := 1;
    mysql> INSERT INTO Days SELECT day + INTERVAL @offset DAY FROM Days; SET @offset := @offset * 2;
    
    Run Code Online (Sandbox Code Playgroud)

    然后向上箭头并根据需要重复INSERT.它每次都会使行数增加一倍,因此您可以在七个INSERT中获得四个月的行数.

  3. 进行排除联接以查找报告表中不匹配的日期:

    SELECT d.day FROM Days d 
    LEFT OUTER JOIN Reports r ON d.day = DATE(r.reportdatetime) 
    WHERE d.day BETWEEN '2011-01-01' AND '2011-04-30' 
        AND r.reportdatetime IS NULL;`
    
    Run Code Online (Sandbox Code Playgroud)