gpt4 book ai didi

sql - (self) 按时间间隔加入

转载 作者:行者123 更新时间:2023-12-04 12:53:17 26 4
gpt4 key购买 nike

我在 oracle 数据库中有一个表。架构是

create table PERIODS
(
ID NUMBER,
STARTTIME TIMESTAMP,
ENDTIME TIMESTAMP,
TYPE VARCHAR2(100)
)

我有两个不同的 TYPE's : TYPEATYPEB .它们具有独立的开始和结束时间,并且可以重叠。我想找到的是 TYPEB 的周期在 TYPEA 的给定时间段内开始、完全包含或结束.

这是我到目前为止想到的(带有一些示例数据)
WITH mydata 
AS (SELECT 100 ID,
To_timestamp('2015-08-01 11:00', 'YYYY-MM-DD HH24:MI') STARTTIME,
To_timestamp('2015-08-01 11:20', 'YYYY-MM-DD HH24:MI') ENDTIME,
'TYPEA' TYPE
FROM dual
UNION ALL
SELECT 110 ID,
To_timestamp('2015-08-01 11:30', 'YYYY-MM-DD HH24:MI') STARTTIME,
To_timestamp('2015-08-01 11:50', 'YYYY-MM-DD HH24:MI') ENDTIME,
'TYPEA' TYPE
FROM dual
UNION ALL
SELECT 120 ID,
To_timestamp('2015-08-01 12:00', 'YYYY-MM-DD HH24:MI') STARTTIME,
To_timestamp('2015-08-01 12:20', 'YYYY-MM-DD HH24:MI') ENDTIME,
'TYPEA' TYPE
FROM dual
UNION ALL
SELECT 105 ID,
To_timestamp('2015-08-01 10:55', 'YYYY-MM-DD HH24:MI') STARTTIME,
To_timestamp('2015-08-01 11:05', 'YYYY-MM-DD HH24:MI') ENDTIME,
'TYPEB' TYPE
FROM dual
UNION ALL
SELECT 108 ID,
To_timestamp('2015-08-01 11:05', 'YYYY-MM-DD HH24:MI') STARTTIME,
To_timestamp('2015-08-01 11:15', 'YYYY-MM-DD HH24:MI') ENDTIME,
'TYPEB' TYPE
FROM dual
UNION ALL
SELECT 111 ID,
To_timestamp('2015-08-01 11:15', 'YYYY-MM-DD HH24:MI') STARTTIME,
To_timestamp('2015-08-01 12:25', 'YYYY-MM-DD HH24:MI') ENDTIME,
'TYPEB' TYPE
FROM dual),
typeas
AS (SELECT starttime,
endtime
FROM mydata
WHERE TYPE = 'TYPEA'),
typebs
AS (SELECT id,
starttime,
endtime
FROM mydata
WHERE TYPE = 'TYPEB')
SELECT id
FROM typebs b
join typeas a
ON ( b.starttime BETWEEN a.starttime AND a.endtime )
OR ( b.starttime BETWEEN a.starttime AND a.endtime
AND b.endtime BETWEEN a.starttime AND a.endtime )
OR ( b.endtime BETWEEN a.starttime AND a.endtime )
ORDER BY id;

这似乎在原则上有效,上面查询的结果是
        ID
----------
105
108
111

所以它选择了三个时期 TYPEB在第一个 TYPEA 内开始或结束时期。

问题是该表有大约 200k 个条目,并且已经达到这个大小,上面的查询很慢 --- 这对我来说非常令人惊讶,因为 TYPEA 的数量。和 TYPEB条目非常低(1-2k)

有没有更有效的方法来执行这种类型的自连接?我在查询中是否遗漏了其他内容?

最佳答案

也许值得一试(最后你还要在oracle中写出最严格的条件,不要问我为什么或相信我,最好做你自己的性能测试):

SELECT
p.id
FROM
periods p
WHERE
EXISTS(SELECT * FROM periods q WHERE
(p.startTime BETWEEN q.startTime AND q.endTime
OR p.endTime BETWEEN q.startTime AND q.endTime
OR p.startTime < q.startTime AND p.endTime > q.endTime -- overlapping correction, remove if not needed
) AND q.type = 'TYPEA'
) AND p.type = 'TYPEB'
ORDER BY
p.id
;

关于sql - (self) 按时间间隔加入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31765919/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com