我在下面有数据集。我想确保对于任何特定ID start_date,end_date以及这两个日期之间的时间段与任何其他ID的日期不重叠。
ID Start_Date End_Date
101 01-01-2001 31-01-2001
102 01-02-2001 28-02-2001
103 26-02-2001 31-03-2016
104 15-03-2001 30-04-2001
105 01-05-2002 31-05-2002
106 05-12-2002 31-12-2002
107 15-12-2002 05-01-2003
为此,我创建了以下查询:
select id,start_date,end_date,
case
when
end_date < max(end_date) over(order by start_date rows unbounded preceding)
then 'overlapping'
when
start_date < max(end_date) over(order by start_date rows unbounded preceding)
then 'overlapping'
else 'non-overlapping'
end as FLAG from table
我的输出低于输出,所有标志为&#39;重叠&#39;这是不正确的。我认为&#39;行前后无界限。正在计算当前行: 你能告诉我我错在哪里吗?
ID Start_Date End_Date Flag
101 01-01-2001 31-01-2001 Overlapping
102 01-02-2001 28-02-2001 Overlapping
103 26-02-2001 31-03-2016 Overlapping
104 15-03-2001 30-04-2001 Overlapping
105 01-05-2002 31-05-2002 Overlapping
106 05-12-2002 31-12-2002 Overlapping
107 15-12-2002 05-01-2003 Overlapping
答案 0 :(得分:1)
有几种方法可以解决这个问题。由于日期范围重叠可能会变得棘手,我会使用Teradata的Period逻辑和自连接:
SELECT
*
FROM
table t1
INNER JOIN table t2 ON
period(t1.start_date, next(t1.end_date)) P_INTERSECT period(t2.start_date, next(t2.end_date)) IS NOT NULL
这会将您的开始和结束日期转换为PERIOD数据类型,然后查找具有相交期间的记录。结果将是两个记录,组合成一个记录,重叠发生在那里。
答案 1 :(得分:0)
你也可以用老式的方式尝试,比如:
CREATE TABLE db.t
(id INT,
start_date DATE,
end_date DATE);
INSERT INTO db.t VALUES (101,'2001-01-01','2001-01-31');
INSERT INTO db.t VALUES (102,'2001-02-01','2001-02-28');
INSERT INTO db.t VALUES (103,'2001-02-26','2001-03-31');
INSERT INTO db.t VALUES (104,'2001-03-15','2001-04-30');
INSERT INTO db.t VALUES (105,'2002-05-01','2002-05-31');
INSERT INTO db.t VALUES (106,'2002-12-05','2002-12-31');
INSERT INTO db.t VALUES (107,'2002-12-01','2003-01-05');
SELECT
t.id,
t.start_date,
t.end_date,
MAX(CASE WHEN o.id IS NULL THEN 'non-overlapping'
ELSE 'overlaps with' || o.id END) AS flag
FROM
db.t t LEFT OUTER JOIN
db.t o ON
t.start_date < o.end_date AND
t.end_date >= o.start_date AND
t.id <> o.id
GROUP BY 1,2,3
返回(手动排序)
id start_date end_date flag
101 01/01/2001 01/31/2001 non-overlapping
102 02/01/2001 02/28/2001 overlaps with 103
103 02/26/2001 03/31/2001 overlaps with 104
104 03/15/2001 04/30/2001 overlaps with 103
105 05/01/2002 05/31/2002 non-overlapping
106 12/05/2002 12/31/2002 overlaps with 107
107 12/01/2002 01/05/2003 overlaps with 106