将Previous Row的RefToDate变为下一行TSQL的RefFromDate

时间:2013-08-28 04:29:59

标签: sql sql-server tsql

我有一张包含以下格式数据的表格:

ProjID   ProjName    RefDate    
-------- ----------- ---------- 
1        A           08/02/2013 
1        A           08/03/2013 
1        A           08/15/2013 
2        B           08/02/2013 
2        B           08/03/2013 
2        B           08/15/2013 
2        B           08/20/2013 

我想要一个如下所示的结果集:

ProjID   ProjName    StartDate  EndDate    
-------- ----------- ---------- ------------
1        A           08/02/2013 08/02/2013 
1        A           08/02/2013 08/03/2013
1        A           08/03/2013 08/15/2013
2        B           08/02/2013 08/02/2013
2        B           08/02/2013 08/16/2013 
2        B           08/16/2013 08/20/2013 
2        B           08/20/2013 08/22/2013

StartDate是从上一行的refdate复制的。

如何使用TSQL语句来提出上面提到的结果集?我可以做一次迭代,但这不是恕我直言的最佳方式。

2 个答案:

答案 0 :(得分:1)

如果您运行SQL2005或更高版本,则可以

  • self join选择下一个日期
  • union每个项目的第一行

类似的东西:

;
WITH    ProjectDataRanked
      AS ( SELECT   ProjID ,
                    ProjName ,
                    RefDate ,
                    ROW_NUMBER() OVER ( PARTITION BY ProjID, ProjName ORDER BY RefDate ) RN
           FROM     ProjectData
         )
SELECT  ProjectData.ProjID ,
        ProjectData.ProjName ,
        ProjectData.RefDate AS StartDate ,
        MIN(ProjectDataNext.RefDate) AS EndDate
FROM    ProjectData
        INNER JOIN ProjectData ProjectDataNext ON ProjectData.ProjID = ProjectDataNext.ProjID
                                                  AND ProjectData.ProjName = ProjectDataNext.ProjName
                                                  AND ProjectData.RefDate > ProjectDataNext.RefDate
GROUP BY ProjectData.ProjID ,
        ProjectData.ProjName ,
        ProjectData.RefDate
UNION
SELECT  ProjID ,
        ProjName ,
        RefDate AS StartDate ,
        RefDate AS EndDate
FROM    ProjectDataRanked
WHERE   RN = 1
ORDER BY ProjID ,
        ProjName ,
        StartDate ,
        EndDate

答案 1 :(得分:1)

如果您使用的是SQL Server 2005/2008,那么可以试试这个

;with cte as
(
  select *,
  row_number() over (partition by projid order by refdate) rn
  from projects
)
select c.projid, c.projname,
coalesce(l.refdate, c.refdate) as startdate,
c.refdate as enddate
from cte c
left outer join cte l 
  on c.projid = l.projid and (c.rn -1) = l.rn
order by 1,3,4

SQL DEMO

SQL Server 2012支持LAG可用于实现相同结果的函数

select 
c.projid, c.projname,
coalesce(lag(c.refdate)
         over (partition by projid 
               order by refdate),c.refdate)
as startdate,
c.refdate as enddate
from projects c
order by 1,3,4;

SQL DEMO for 2012