[英]Oracle SQL comparing two columns in a for loop
I am trying to compare two columns in an SQL table based on two dates. 我试图基于两个日期比较SQL表中的两列。 The table is set up so the each person in table A has a foreign key to another table B, each person can have multiple entries in table B. Each entry in table B contains a start date and end date and I am trying to grab each person that has an overlap in table B so the Start Date of one of the entries is before the End Date of any other entry.
设置该表是为了使表A中的每个人都具有另一个表B的外键,每个人可以在表B中具有多个条目。表B中的每个条目都包含开始日期和结束日期,我正尝试抓住每个表B中有重叠的人员,因此其中一个条目的开始日期早于任何其他条目的结束日期。
So John Doe in table A has two entries in table B where the start day of Entry 1 is April 5th 2015 and end date of April 6th 2016 and the second entry is January 10th 2016 and ends January 10th 2017, so I would want to include this person in my result set. 因此,表A中的John Doe在表B中有两个条目,其中条目1的开始日期是2015年4月5日,结束日期是2016年4月6日,第二个条目是2016年1月10日并且结束于2017年1月10日,所以我想包括我的结果集中的这个人。
However Jane Doe in table A as two entries in table B 但是表A中的Jane Doe作为表B中的两个条目
Entry 1: SD April 10th 2014 End April 10th 2015
Entry 2: SD May 11th 2015 End May 11th 2016
So I would not like to I include Jane Doe in my result set. 因此,我不想在结果集中包含Jane Doe。
I am thinking I need to use two nested for loop in the where part of the select statement flipping a variable back and forth depending on whether or not I want to include this person. 我想我需要在select语句的where部分中使用两个嵌套的for循环,这取决于我是否要包含此人,来回翻转变量。
Something along the lines of 遵循以下原则
Select * from A
where
(reset variable
for b in
(select * from b.id = A.b_id); loop
for btwo in
(select * from b.id = A.b_id); loop
// set variable based on start / end date
// if I want to include set var = 1 else 0
end loop;
end loop;)
variable = 1;
You've tagged this question for two database systems - my answer pertains to Oracle. 您已为两个数据库系统标记了该问题-我的回答与Oracle有关。
There's no need to use a loop here as you can use the SQL analytic function LAG to handle this sort of problem. 此处无需使用循环,因为您可以使用SQL分析函数LAG来处理此类问题。
The following will provide the results you're looking for: 以下内容将提供您想要的结果:
SELECT DISTINCT T.NAME
FROM (SELECT A.NAME,
B.START_DATE,
B.END_DATE,
LAG(B.START_DATE) OVER (PARTITION BY A.NAME ORDER BY B.NAME, B.START_DATE) AS PREV_START,
LAG(B.END_DATE) OVER (PARTITION BY A.NAME ORDER BY B.NAME, B.START_DATE) AS PREV_END
FROM A
INNER JOIN B
ON B.NAME = A.NAME
ORDER BY A.NAME) T
WHERE (T.START_DATE BETWEEN T.PREV_START AND T.PREV_END) OR
(T.END_DATE BETWEEN T.PREV_START AND T.PREV_END) OR
(T.PREV_START BETWEEN T.START_DATE AND T.END_DATE) OR
(T.PREV_END BETWEEN T.START_DATE AND T.END_DATE);
Here is my suggestion. 这是我的建议。 To get the overlaps you can use:
要获得重叠,可以使用:
select b.*
from tableb b
where exists (select 1
from tableb b2
where b.aid = b2.aid and
b.startdate < b2.enddate and b.enddate > b.startdate
);
The logic is simple. 逻辑很简单。 Two time spans overlaps if the first begins before the second ends, and the first ends after the second begins.
如果第一个时间间隔在第二个时间间隔之前开始,而第一个时间间隔在第二个时间间隔之后开始,则两个时间间隔重叠。
To get the table a values: 要获取表的值:
with overlaps as (
select b.*
from tableb b
where exists (select 1
from tableb b2
where b.aid = b2.aid and
b.startdate < b2.enddate and b.enddate > b.startdate
)
)
select a.*
from tablea a
where a.aid in (select o.aid from overlaps o);
Note: depending on how you define "overlap" you might want <=
and >=
for the comparisons. 注意:根据您定义“重叠”的方式,您可能需要
<=
和>=
进行比较。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.