1

我有一个表格,其中包含以下格式的数据:

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 语句得出上述结果集?我可以进行迭代,但恕我直言,这不是最佳方法。

4

2 回答 2

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
于 2013-08-28T04:52:40.600 回答
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 演示

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;

2012 年的 SQL 演示

于 2013-08-28T04:53:00.170 回答