Row_Number()在此查询上

时间:2014-07-21 14:39:43

标签: sql-server sql-server-2008

我试图在此日期范围查询中包含行号。当我添加最后一个行号子查询时,它会将结果更改为不正确,我无法弄清楚原因。有更好的方法吗?

 DECLARE @MainHospital varchar(50) = 'Hospital1';

WITH Start AS
(
    SELECT 
           MAX(Time_Stamp) as StartDate, 
           DATEADD(day, 90, MAX(Time_Stamp)) as EndDate
    FROM Survey
    WHERE MainHospital = @MainHospital

),
Results AS
(
   SELECT StartDate, EndDate from Start
   UNION
   SELECT DATEADD(DAY, 1, EndDate), DATEADD(day, 91, EndDate) FROM Start
   UNION
   SELECT DATEADD(DAY, 92, EndDate), DATEADD(day, 182, EndDate) FROM Start
   UNION
   SELECT DATEADD(DAY, 183, EndDate), DATEADD(day, 273, EndDate) FROM Start
   UNION
   SELECT DATEADD(DAY, 274, EndDate), DATEADD(day, 364, EndDate) FROM Start
),
cte3 AS(
 SELECT LEFT(StartDate,11) AS StartDate, LEFT(EndDate,11) AS EndDate FROM Results
)
SELECT ROW_NUMBER() OVER(ORDER BY StartDate) ranks,
StartDate, EndDate
FROM cte3

给出以下结果,开始日期是错误的。 12月应该是6月10日,因为那是最大的Time_Stamp。

    ranks                StartDate   EndDate
-------------------- ----------- -----------
1                    Dec  9 2014 Mar  9 2015
2                    Jun  9 2015 Sep  7 2015
3                    Jun 10 2014 Sep  8 2014
4                    Mar 10 2015 Jun  8 2015
5                    Sep  9 2014 Dec  8 2014

3 个答案:

答案 0 :(得分:4)

试试这个:

DECLARE @MainHospital varchar(50) = 'Hospital1';

WITH Start AS
(
    SELECT 
           MAX(Time_Stamp) as StartDate, 
           DATEADD(day, 90, MAX(Time_Stamp)) as EndDate
    FROM Survey
    WHERE MainHospital = @MainHospital

),
Results AS
(
   SELECT StartDate, EndDate from Start
   UNION
   SELECT DATEADD(DAY, 1, EndDate), DATEADD(day, 91, EndDate) FROM Start
   UNION
   SELECT DATEADD(DAY, 92, EndDate), DATEADD(day, 182, EndDate) FROM Start
   UNION
   SELECT DATEADD(DAY, 183, EndDate), DATEADD(day, 273, EndDate) FROM Start
   UNION
   SELECT DATEADD(DAY, 274, EndDate), DATEADD(day, 364, EndDate) FROM Start
),
cte3 AS(
 SELECT StartDate, EndDate FROM Results
)
SELECT ROW_NUMBER() OVER(ORDER BY StartDate) ranks,
LEFT(StartDate,11) AS StartDate, LEFT(EndDate,11) AS EndDate
FROM cte3

答案 1 :(得分:2)

您的问题是,在创建CTE3后,您将获得varchar个值的日期。因此,行号按字母顺序排序,而不是日期。要解决这个问题,请在订购时按日期进行投射:

SELECT ROW_NUMBER() OVER(ORDER BY CAST(StartDate as DATETIME)) ranks,
StartDate, EndDate
FROM cte3

Demo

然而,更好的方法是将StartDateEndDate保留为CTE3中的DateTime值并最后将它们转换为字符串,如下所示:

cte3 AS
(
 SELECT StartDate, EndDate FROM Results
)

SELECT ROW_NUMBER() OVER(ORDER BY StartDate) ranks,
LEFT(StartDate,11) AS StartDate, LEFT(EndDate,11) AS EndDate
FROM cte3

答案 2 :(得分:1)

更改此部分:

cte3 AS
(
 SELECT CAST(StartDate AS DATE) AS StartDate, CAST(EndDate AS DATE) AS EndDate FROM Results
)

无需左侧11来获取日期部分。