MySQL:查找日期范围内缺失的日期

发布于 2024-11-17 21:12:32 字数 258 浏览 3 评论 0原文

我需要一些有关 mysql 查询的帮助。我有一个数据库表,其中包含从 2011 年 1 月 1 日到 2011 年 4 月 30 日的数据。每个日期都应该有一条记录。我需要查明表中是否缺少任何日期。

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

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

有什么建议吗?

I need some help with a mysql query. I've got db table that has data from Jan 1, 2011 thru April 30, 2011. There should be a record for each date. I need to find out whether any date is missing from the table.

So for example, let's say that Feb 2, 2011 has no data. How do I find that date?

I've got the dates stored in a column called reportdatetime. The dates are stored in the format: 2011-05-10 0:00:00, which is May 5, 2011 12:00:00 am.

Any suggestions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

碍人泪离人颜 2024-11-24 21:12:32

这是第二个答案,我会单独发布。

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;

这是一个自连接,它报告一个日期,使得不存在后面的日期的行。

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

This is a second answer, I'll post it separately.

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;

This is a self-join that reports a date such that no row exists with the date following.

This will find the first day in a gap, but if there are runs of multiple days missing it won't report all the dates in the gap.

尾戒 2024-11-24 21:12:32
  1. CREATE TABLE Days (day DATE PRIMARY KEY);

  2. 填写 Days< /code> 包含您要寻找的所有日子。

    mysql>插入天数值 ('2011-01-01');
    mysql>设置@偏移量:= 1;
    mysql> INSERT INTO Days SELECT day + INTERVAL @offset DAY FROM Days;设置@offset := @offset * 2;
    

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

  3. 执行排除联接以查找报告表中没有匹配项的日期:

    从 d 天中选择 d.day 
    左外连接报告 r ON d.day = DATE(r.reportdatetime) 
    “2011-01-01”和“2011-04-30”之间的 d.day 
        AND r.reportdatetime 为 NULL;`
    
  1. CREATE TABLE Days (day DATE PRIMARY KEY);

  2. Fill Days with all the days you're looking for.

    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;
    

    Then up-arrow and repeat the INSERT as many times as needed. It doubles the number of rows each time, so you can get four month's worth of rows in seven INSERTs.

  3. Do an exclusion join to find the dates for which there is no match in your reports table:

    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;`
    
陪我终i 2024-11-24 21:12:32

可以使用更复杂的单个查询来完成,但我将显示一个带有临时表的代码,仅用于说明:

获取我们有记录的所有日期:

CREATE TEMP TABLE AllUsedDates

SELECT DISTINCT reportdatetime
INTO AllUsedDates;

现在添加 5 月 1 日,以便我们跟踪 04 -30

INSERT INTO AllUsedData ('2011-05-01')

如果没有“第二天”,我们就发现了一个缺口:

SELECT A.NEXT_DAY
FROM
    (SELECT reportdatetime AS TODAY, DATEADD(reportdatetime, 1) AS NEXT_DAY FROM AllUsed Dates) AS A
WHERE
    (A.NEXT_DATE NOT IN (SELECT reportdatetime FROM AllUsedDates)
    AND
    A.TODAY <> '2011-05-01') --exclude the last day

It could be done with a more complicated single query, but I'll show a pseudo code with temp table just for illustration:

Get all dates for which we have records:

CREATE TEMP TABLE AllUsedDates

SELECT DISTINCT reportdatetime
INTO AllUsedDates;

now add May 1st so we track 04-30

INSERT INTO AllUsedData ('2011-05-01')

If there's no "next day", we found a gap:

SELECT A.NEXT_DAY
FROM
    (SELECT reportdatetime AS TODAY, DATEADD(reportdatetime, 1) AS NEXT_DAY FROM AllUsed Dates) AS A
WHERE
    (A.NEXT_DATE NOT IN (SELECT reportdatetime FROM AllUsedDates)
    AND
    A.TODAY <> '2011-05-01') --exclude the last day
舞袖。长 2024-11-24 21:12:32

如果您的意思是 reportdatetime 具有“2011 年 2 月 2 日”条目,但与该日期关联的其他字段不存在,如下表快照所示,

reportdate  col1    col2
5/10/2011   abc xyz
2/2/2011        
1/1/2011    bnv oda

那么此查询工作正常

select reportdate from dtdiff where reportdate not in (select df1.reportdate from dtdiff df1, dtdiff df2 where df1.col1 = df2.col1)

If you mean reportdatetime has the entry of "Feb 2, 2011" but other fields associated to that date are not present like below table snap

reportdate  col1    col2
5/10/2011   abc xyz
2/2/2011        
1/1/2011    bnv oda

then this query works fine

select reportdate from dtdiff where reportdate not in (select df1.reportdate from dtdiff df1, dtdiff df2 where df1.col1 = df2.col1)
万水千山粽是情ミ 2024-11-24 21:12:32

SELECT DATE(t1.datefield) + INTERVAL 1 DAY AS missing_date FROM table t1 LEFT OUTER JOIN table t2 ON DATE(t1.datefield) = DATE(t2.datefield) - INTERVAL 1 DAY WHERE DATE(t1.datefield) BETWEEN '2020-01-01' AND '2020-01-31' AND DATE(t2.datefield) IS NULL;

如果您想获取日期时间字段中缺少的日期,请尝试此操作

SELECT CAST(t1.datetime_field  as DATE) + INTERVAL 1 DAY AS missing_date FROM table t1 LEFT OUTER JOIN table t2 ON CAST(t1.datetime_field  as DATE) = CAST(t2.datetime_field  as DATE) - INTERVAL 1 DAY WHERE CAST(t1.datetime_field  as DATE) BETWEEN '2020-01-01' AND '2020-07-31' AND CAST(t2.datetime_field  as DATE) IS NULL;

Try this

SELECT DATE(t1.datefield) + INTERVAL 1 DAY AS missing_date FROM table t1 LEFT OUTER JOIN table t2 ON DATE(t1.datefield) = DATE(t2.datefield) - INTERVAL 1 DAY WHERE DATE(t1.datefield) BETWEEN '2020-01-01' AND '2020-01-31' AND DATE(t2.datefield) IS NULL;

If you want to get missing dates in a datetime field use this.

SELECT CAST(t1.datetime_field  as DATE) + INTERVAL 1 DAY AS missing_date FROM table t1 LEFT OUTER JOIN table t2 ON CAST(t1.datetime_field  as DATE) = CAST(t2.datetime_field  as DATE) - INTERVAL 1 DAY WHERE CAST(t1.datetime_field  as DATE) BETWEEN '2020-01-01' AND '2020-07-31' AND CAST(t2.datetime_field  as DATE) IS NULL;
浮生未歇 2024-11-24 21:12:32

上面的解决方案似乎有效,但至少在我的数据库中它们看起来非常慢(可能需要几个小时,我只等了 30 分钟)。

该子句在同一数据库中花费的时间不到一秒钟(当然,您需要手动重复数十次,并且可能更改函数名称以查找实际日期)。 pvm = 我的日期时间,天气 = 我的桌子。

mysql>选择年份(pvm) as _year,count(distinct(date(pvm))) as _days from WEATHER whereyear(pvm)>=2000 and Month(pvm)=1 group by _year order by _year asc;

--亚子

The solutions above seem to work, but they seem EXTREMELY slow (taking possibly hours, I waited for 30 min only) at least in my database.

This clause takes less than a second in same database (of course you need to repeat it manually dozen times and possibly change function names to find the actual dates). pvm = my datetime, WEATHER = my table.

mysql> select year(pvm) as _year,count(distinct(date(pvm))) as _days from WEATHER where year(pvm)>=2000 and month(pvm)=1 group by _year order by _year asc;

--ako

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文