2012-11-27 182 views
1

我有一个小桌子,看起来像这样:如何在sql中获取开始日期和结束日期?

PLAN YRMTH 
A2BKG 197001 
A2BKG 200205 
A2BKG 200308 
A2BKG 200806 

从这个表中,如何获取一个表,如下面的一个?

PLAN STARTDATE ENDDATE 
    A2BKG 197001  200205 
    A2BKG 200205  200308 
    A2BKG 200308  200806 
    A2BKG 200806  NULL 

回答

2

试试这个

;with cte as 
(select *, ROW_NUMBER() over (partition by [plan] order by yrmth) rn from yourtable) 
    select 
     t1.[plan], 
     t1.YRMTH as startdate, 
     t2.YRMTH as enddate 
    from cte t1 
     left join cte t2 on t1.[plan]=t2.[plan] 
      and t1.rn=t2.rn-1 
+0

谢谢!这是惊人的。我需要重新学习CTE的知识,它是超级有用的。 :) – Sarah

0

像这样的东西可以帮助:

SELECT 
[PLAN], 
YRMTH AS STARTDATE, 
(SELECT MIN(YRMTH) FROM yourTable T 
WHERE T.[Plan] = yourTable.[Plan] AND T.YRMTH > Test1.YRMTH) AS ENDDATE 
FROM yourTable 
1

这就是我想在Oracle 同样是在SQL服务器2012可作为以及... .my坏:(

select plan,yrmth,lead(yrmth) over (partition by lower(plan) order by rowid) from tbl; 
0
select t1.PLAN, t2.STARTDATE, 
(select top 1 STARTDATE from table t2 where t1.PLAN =t2.PLAN 
        and t1.STARTDATE<t2.STARTDATE) as ENDDATE 
from table t1 
0

临时表解决方案来自我。

-- Create a temp table, containing an extra column, ID 
DECLARE @orderedPlans 
(
    ID int, 
    Plan varchar(64), 
    YrMth int 
) 

-- Use contents of your table, plus ROW_NUMBER, to populate 
-- temp table. ID is sorted on Plan and YrMth. 
-- 
INSERT INTO 
    @orderedPlans 
(
    ID, 
    Plan, 
    YrMth 
) 
SELECT ROW_NUMBER() OVER (ORDER BY Plan, YrMth) AS ID, 
    Plan, 
    YrMth 
FROM 
    YourTable 

-- Now join your temp table on itself 
-- Because of the ROW_NUMBER(), we can use ID - 1 as a join 
-- Also join on Plan, so that the query can handle multiple plans being 
-- in the table 
SELECT 
    p1.Plan, 
    p1.YrMth AS StartDate, 
    p2.YrMth AS EndDate 
FROM 
    @orderedPlans p1 
LEFT JOIN 
    @orderedPlans p2 
ON 
    p1.Plan = p2.Plan 
AND p1.ID = p2.ID - 1 
+0

你为什么要使用一个临时表?它可以作为一个简单的CTE或内部选择来解决。在内存表中插入值然后选择它们是一个较慢的解决方案。 –

+1

一旦规模扩大,内部选择可能会比临时表慢得多。你有多说1M行吗? –

相关问题