2013-12-18 102 views
-2

我有一个表A作为SQL表列填充

ID EFF_DT 
1 2/12/2013 
2 4/12/2013 
3 6/3/2013 
4 5/15/2013 

我需要一个临时表#TEMP作为

ID EFF_DT  END_DATE 
1 2/12/2013 4/11/2013 
2 4/12/2013 5/14/2013 
3 5/15/2013 6/2/2013 
4 6/3/2013  cURRDATE 

什么是实现这一目标的最佳途径? END_DATE为EFF_DT比下一EFF_DT少的顺序排序

+0

有人可以调整列格式pls – user3083816

+0

对不起,忽略ID列..它不重要 – user3083816

+0

你试过什么代码,你的结果是什么? – Theresa

回答

1

的第1天可以使用相关子查询(请在任意查询引擎)做到这一点:

select a.*, 
     coalesce((select min(efe_dt) + 1 
       from a a2 
       where a2.efe_dt > a.efe_dt 
       ), CURRENT_DATE) as end_date 
from a; 

一些注意事项,基于SQL的方言。减去一天的代码可以采用各种格式(例如使用dateadd()函数)。当前日期时间的常量/函数也因方言而异。

某些SQL引擎支持ANSI标准lag()/lead()函数。这使代码更容易。下面是你如何可以在SQL Server 2012中做到这一点:

select a.*, 
     coalesce(dateadd(day, -1, lead(efe_dt) over (order by efe_dt)), 
       cast(get_date() as date) 
       ) as end_date 
from a; 
+0

非常好!我从来没有见过领先。然而,它错过了系列中的最后一天 - 它必须在封面下面做一个自我内在联结? –

+0

只是要说清楚,这只是你第二个错过了最后一行。你的第一个很好,比我的快得多。 –

+0

@simonatrcl。 。 。你是什​​么意思“错过最后一行”?第二个查询是从'a'选择所有行,所以不应该丢失行。 –

0

写意SQL:

select a1.I2, a1.eff_date, case when a2.eff_date is null then getdate() 
           else DateAdd(D, -1, a2.eff_date) end End_date 
from A a1 
left outer join A a2 on a2.eff_date > a1.eff_date 
where a2.eff_date is null 
or a2.eff_date = (select min(a3.eff_date) from A a3 where a3.eff_date > a1.eff_date) 

看起来像它的工作原理。