间隙检测 - 确定跳过/错过的日期
gap detection - identify what date was skipped / missed
我有一个数据库 table,其中包含具有 ID 和 date - 日期范围的记录。
某些 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
这将为您提供一个行列表,其中包含自身与上一行之间的间隔以及日期范围(不是列表)。
我有一个数据库 table,其中包含具有 ID 和 date - 日期范围的记录。
某些 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
这将为您提供一个行列表,其中包含自身与上一行之间的间隔以及日期范围(不是列表)。