差距检测-确定跳过/错过的日期

时间:2019-07-05 11:43:29

标签: mysql sql datetime gaps-and-islands

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

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

2019- 01 -01(日期)和2019- 01 -01(日期)代表一个月(年份)

2018- 09 -01(日期)和2018- 11 -01(日期)代表一个月的间隔( 9月1日-11月31日)

enter image description here

所以我想要获得的ID是差距,错过的月份或月份间隔的位置。如何使用sql解决此问题?我应该从哪开始?

2 个答案:

答案 0 :(得分:1)

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

 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;

答案 1 :(得分:1)

在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

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