SQL查找日期间隔

时间:2015-03-28 00:41:05

标签: sql oracle

我有一张时间段的表格(时间段没有重叠):

start_date        end_date
-----------------------------
12-aug-14         12-nov-14
12-jan-15         12-apr-15
12-jun-15         12-aug-15
... 5 more

我试图在时间段之间找到 - 比如:

12-nov-14         12-jan-15
12-apr-15         12-jun-15
...

但是,我的查询给出了所有时间段差异,例如:

12-nov-14         12-jan-15
12-nov-14         12-jun-15

我的疑问是:

select 
    l1.end_date, l2.start_date 
from 
    lease l1, lease l2 
where 
    l1.place_no = 'P1' and l2.place_no = 'P1' 
    and l2.start_date > l1.end_date 
order by 
    l1.end_date asc;

有什么想法吗?

谢谢!

3 个答案:

答案 0 :(得分:2)

使用lead()。这就是该功能的设计目标:

select l.*,
       lead(start_date) over (partition by place_no order by start_date) as next_start_date,
       (lead(start_date) over (partition by place_no order by start_date) as next_start_date - end_date) as gap
from lease l
where l1.place_no = 'P1';

不需要join甚至子查询 - 除非您想要消除具有NULL值的附加行,因为没有下一个值。

答案 1 :(得分:1)

sort您的表格,使用rownum,然后使用join

WITH CTE AS (
    SELECT 
       START_DATE,
       END_DATE,
       ROWNUM AS RN
FROM ( SELECT START_DATE, END_DATE FROM TABLE_NAME ORDER BY 1,2)
)
SELECT T1.END_DATE, T2.START_DATE
FROM CTE T1 JOIN CTE T2 ON T2.RN=T1.RN+1

答案 2 :(得分:0)

这有点棘手。您正在创建一个笛卡尔坐标,它是关闭的,在您创建笛卡尔坐标之后,使用分组将其限制为仅限于起始行和最小的行尾:

select
 l1.end_date,
 min(l2.start_date)
from 
    lease l1 
    inner join lease l2 ON
        l1.place_no = l2.place_no and
        l2.start_date >= l1 end_date
where 
    l1.place_no = 'P1'
group by
    l1.start_date
having
    l2.start_date != l1.end_date

很抱歉关于你加入你的加入语法,它可以帮助我更好地组织我的SQL。