间隙检测 - 确定跳过/错过的日期

gap detection - identify what date was skipped / missed

我有一个数据库 table,其中包含具有 IDdate - 日期范围的记录。

某些 ID 的导入日期最初是 date to 列。我只对感兴趣,像2018-06-0100:00:00这样的日期代表了2018年整个iune月。(我对日期和时间不感兴趣,01天设置是因为我不能使用 00)。

2019-01-01(date from)和2019-01-01(date to)代表一个月(一月)。

2018-09-01(date from)和2018-11-01(date to)代表间隔几个月(9月01日-11月31日)

所以我想要的是获取 ID-s,其中有间隙、错过的月份或月份间隔。如何使用 sql 解决此问题?我从哪条路开始?

如果您不使用 8.0,您可以创建一个工作 table 来保存数据:

 CREATE TABLE _gap_cal (
      ID int not null,
      date_to date not null,
      rid int not null auto_increment,
      date_from date null,
      PRIMARY KEY (ID,rid)
 ) ENGINE=MYISAM;

然后像这样填充数据:

INSERT _gap_cal(ID,date_from,date_to,rid)
SELECT ID,COALESCE(date_from,'1900-01-01'),date_to,NULL
FROM your_data_table
ORDER BY ID,date_to;

为了测试,我直接插入了一些数据:

INSERT _gap_cal(ID,date_from,date_to,rid)
VALUES (6545,'1900-01-01','2018-06-01',NULL),
  (6545,'2018-09-01','2018-11-01',NULL),
  (6545,'2019-01-01','2019-01-01',NULL),
  (2421,'2019-04-01','2019-06-01',NULL),
  (2421,'2019-07-01','2019-07-01',NULL),
  (2421,'2019-09-01','2019-11-01',NULL);

SELECT * FROM _gap_cal;

以下查询将为您提供有间隔的 ID 和日期范围:

SELECT c.ID,c.date_from,c.date_to, p.date_from as previous_date_from
FROM _gap_cal p
INNER JOIN _gap_cal c
ON p.ID=c.ID
AND p.rid=c.rid-1
AND TIMESTAMPADD(MONTH,1, p.date_to)<>c.date_from
ORDER BY c.ID,c.date_from;

在 MySQL 5.x 中,您可以使用相关查询(非常慢)来识别差距。查询的粗略概述:

SELECT *
FROM (
    SELECT id, start_date, start_date - INTERVAL 1 MONTH AS prev_end_date_exp, (
        SELECT end_date
        FROM yourdata AS x
        WHERE id = t.id AND end_date < t.start_date
        ORDER BY end_date DESC
        LIMIT 1
    ) AS prev_end_date_act
    FROM yourdata AS t
) AS sq
WHERE prev_end_date_exp <> prev_end_date_act

这将为您提供一个行列表,其中包含自身与上一行之间的间隔以及日期范围(不是列表)。