如何在mysql表中查找缺失的行(日期)?

时间:2011-04-02 10:53:35

标签: mysql gaps-and-islands

我在这里尝试了几个主题:How to find missing data rows using SQL?,但我无法在我的情况下使用它。

我在MySQL中有一个名为posts的表,我每天都会在其中保存用户日记。有时用户忘记写一天的帖子,我想让他们以后再提交。 所以数据库结构如下:

date           userid
2011-10-01     1
2011-10-02     1
(missing)
2011-10-04     1
2011-10-05     1
(missing)
2011-10-07     1

所以我想在这个缺失行表中向用户显示缺少日期的下拉列表,这样他就可以选择他想要提交帖子的日期。

我该怎么做? 感谢。

3 个答案:

答案 0 :(得分:5)

查找缺少日期的最简单方法是使用日历表。我发布了code to create and populate a calendar table for PostgreSQL;你应该能够毫无困难地适应它。

使用日历表,您的查询非常简单,易于理解。要查找2011年10月的缺失日期,您可以使用这些内容。 (猜猜你的“帖子”表。)

select c.cal_date
from calendar c
left join posts p on (c.cal_date = p.date)
where p.date is null
  and c.cal_date between '2011-10-01' and '2011-10-31'
  and p.userid = 1
order by c.cal_date

答案 1 :(得分:3)

如果您有日期表,这些类型的查询最容易解决。 在您的数据库中,将此批处理作为一次性运行以创建填充日期表。

DROP PROCEDURE IF EXISTS FillDateTable;

delimiter //
CREATE PROCEDURE FillDateTable()
    LANGUAGE SQL
    NOT DETERMINISTIC
    CONTAINS SQL
    SQL SECURITY DEFINER
    COMMENT ''
BEGIN
  drop table if exists datetable;
  create table datetable (thedate datetime primary key, isweekday smallint);

  SET @x := date('2000-01-01');
  REPEAT 
    insert into datetable (thedate, isweekday) SELECT @x, case when dayofweek(@x) in (1,7) then 0 else 1 end;
    SET @x := date_add(@x, interval 1 day);
    UNTIL @x >= '2030-12-31' END REPEAT;
END//
delimiter ;

CALL FillDateTable;

然后你可以使用常规LEFT JOIN

SELECT thedate
FROM datetable
LEFT JOIN posts on posts.date = datetable.thedate
WHERE posts.date IS NULL

当然,您不希望2000年到2030年之间的所有“缺失”日期。将其限制在posts表中的MIN和MAX日期(对于用户而言),即

SELECT thedate
FROM datetable
INNER JOIN (select min(date) postStart, max(date) postEnd
            FROM posts
            where userid=123) p on datetable.thedate BETWEEN p.postStart and p.postEnd
LEFT JOIN posts on posts.date = datetable.thedate
WHERE posts.date IS NULL

答案 2 :(得分:1)

您可以每次(结束日期)自动输入一个空帖子,其中包含空标题,空内容但实际日期。然后,如果用户想要添加前一天的帖子,则显示所有具有空标题和内容的帖子并更新他选择的帖子。

这不应该是一个空间问题,如果他们写的比他们想念的还多。例如,如果他们写了4天而错过了1。

此外,您将运行脚本并删除具有空标题,空内容和早于X天的日期的条目。如果他们没有添加X天的遗失帖子,他们可能永远不会。

如果我的解决方案很简单/过于抽象,我道歉。