在列中查找下一个日期值

时间:2012-03-28 20:15:33

标签: sql

我有一个包含以下列和示例值的大表:

ID  Ser     Reg Date
1   12345   001 1/3/2011
1   12345   001 2/2/2011
1   12345   002 1/3/2011
1   12345   002 2/2/2011
2   23456   001 1/3/2011
2   23456   001 2/7/2011
2   23456   001 3/5/2011

我在之前的帖子SQL中尝试了这个查询 - 选择下一个日期查询 - 但没有得到预期的结果:

SELECT 
    mytable.id, 
    mytable.date, 
    ( 
        SELECT 
            MIN(mytablemin.date) 
        FROM mytable AS mytablemin 
        WHERE mytablemin.date > mytable.date 
    ) AS NextDate 
FROM mytable 

这就是我想要实现的目标:

ID     Ser         Reg     curr_Date   prev_Date
1      12345       001     2/2/2011    1/3/2011
1      12345       002     2/2/2011    1/3/2011
2      23456       001     2/7/2011    1/5/2011
2      23456       001     3/5/2011    2/7/2011

感谢您对此任务的任何帮助。

2 个答案:

答案 0 :(得分:0)

相关子查询中缺少一个条件,将mytable表的mytablemin副本与mytable一起加入。此外,您将删除没有NextDate的记录 - 但如果通过从结果集中删除它只存在组(Id,Ser,Reg)中的一个记录,则可能会产生不正确的结果。

select * from
(
    SELECT 
        mytable.id, 
        mytable.date, 
        ( 
            SELECT 
                MIN(mytablemin.date) 
            FROM mytable AS mytablemin 
            WHERE mytablemin.date > mytable.date 
              and mytablemin.id = mytable.id
              and mytablemin.Ser = mytable.Ser
              and mytablemin.Reg = mytable.Reg
        ) AS NextDate 
    FROM mytable 
) a
where a.NextDate is not null

这是使用派生表和聚合的版本:

SELECT 
    mytable.id, 
    mytable.date, 
    mytablemin.minDate
FROM mytable 
  inner join
  (
    SELECT mytablemin.id,
           mytablemin.Ser,
           mytablemin.Reg,
           MIN(mytablemin.date) minDate
    FROM mytable AS mytablemin 
    group by mytablemin.id,
           mytablemin.Ser,
           mytablemin.Reg
    having MIN(mytablemin.date) is not null
  ) AS mytablemin
    on mytablemin.id = mytable.id
    and mytablemin.Ser = mytable.Ser
    and mytablemin.Reg = mytable.Reg

答案 1 :(得分:0)

如果您正在使用oracle数据库(因为您没有提到,那么我可以假设任何事情)

然后你可以使用超前和滞后功能/命令..

select id,ser, reg, curr_date ,prev_date
from 
(
select id,ser, reg, ser, date curr_date
LEAD(date, 1, 0) OVER (PARTITION BY id,ser, reg, curr_date ORDER BY date DESC NULLS LAST) prev_date,
)
where prev_date is not null;