Oracle SQL比较for循环中的两列

时间:2015-05-16 18:25:51

标签: sql oracle plsql

我试图根据两个日期比较SQL表中的两列。设置表,以便表A中的每个人都有一个外键到另一个表B,每个人可以在表B中有多个条目。表B中的每个条目包含一个开始日期和结束日期,我试图抓住每个表B中有重叠的人,因此其中一个条目的开始日期在任何其他条目的结束日期之前。

表A中的John Doe在表B中有两个条目,其中条目1的开始日期是2015年4月5日,结束日期是2016年4月6日,第二个条目是2016年1月10日,结束于2017年1月10日,所以我会我希望将此人包含在我的结果集中。

然而,表A中的Jane Doe作为表B中的两个条目

Entry 1: SD April 10th 2014 End April 10th 2015
Entry 2: SD May 11th 2015 End May 11th 2016

所以我不想在我的结果集中包含Jane Doe。

我想我需要在select语句的where部分使用两个嵌套的for循环来回翻转变量,具体取决于我是否要包含此人。

的内容
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;

2 个答案:

答案 0 :(得分:1)

您已为两个数据库系统标记了此问题 - 我的答案与Oracle有关。

由于您可以使用SQL分析函数LAG来处理此类问题,因此无需在此处使用循环。

以下内容将提供您正在寻找的结果:

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);

SQLFiddle here

答案 1 :(得分:0)

这是我的建议。要获得重叠,您可以使用:

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
             );

逻辑很简单。如果第一个在第二个结束之前开始,则两个时间跨度重叠,第一个结束在第二个结束之后结束。

获取表格值:

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);

注意:根据您定义“重叠”的方式,您可能需要<=>=进行比较。