在SQL Server 2008 R2中将行旋转到列中

时间:2015-03-26 06:20:42

标签: sql sql-server-2008-r2 pivot

我有一张这样的表

ProductID  ValidFrom   ValidTo     Count
----------------------------------------
1           10/1/2015  20/12/2015    100
1           1/4/2014  31/12/2014     200
1           2/2/2013  20/9/2013      300

我需要像这样的旋转结果

ProductID      CurrentYearValidity      CurrentYearCount   PreviousYearValidity   PreviousYearCount   PreviousTowYearsValidity  PreviousTwoYearCount
1           10/1/2015 to 20/12/2015        100            1/4/2014 to 31/12/2014       200                9/5/2014 to 20/9/2014     300

如果当前日期介于特定的ValidFrom和ValidTo之间,则应显示在CurrentYearValidity列下。如果今天是2015年3月26日,那么如果2014年3月26日落在特定的ValidFrom和ValidTo之间,那么它应该显示在PreviousYearValidity列下。相应的计数也应显示在适当的列下。

我试过像这样的案例陈述,

select 
    ProductID,
    [CurrentValidity] = case 
                  when CONVERT(datetime,CONVERT(char(10),GETDATE(),101)) BETWEEN CONVERT(datetime,CONVERT(char(10),ValidFrom,101)) AND CONVERT(datetime,CONVERT(char(10),ValidTo,101))
                    then (CONVERT(varchar(30),ValidFrom,110)+' to '+CONVERT(varchar(30),ValidTo,110))
                  else NULL
                END,
     [CurrentYearCount] = case 
                  when CONVERT(datetime,CONVERT(char(10),GETDATE(),101)) BETWEEN CONVERT(datetime,CONVERT(char(10),ValidFrom,101)) AND CONVERT(datetime,CONVERT(char(10),ValidTo,101))
                    then Count
                  else NULL
                END,
     [PreviousYearValidity] = case 
                  when CONVERT(datetime,CONVERT(char(10),GETDATE(),101)) BETWEEN CONVERT(datetime,CONVERT(char(10),ValidFrom,101)) AND CONVERT(datetime,CONVERT(char(10),ValidTo,101))
                    then (CONVERT(varchar(30),ValidFrom,110)+' to '+CONVERT(varchar(30),ValidTo,110))
                  else NULL
                END,
     [PreviousYearCount] = case 
                  when CONVERT(datetime,CONVERT(char(10),GETDATE(),101)) BETWEEN CONVERT(datetime,CONVERT(char(10),ValidFrom,101)) AND CONVERT(datetime,CONVERT(char(10),ValidTo,101))
                    then Count
                  else NULL
                END

但结果显示为

ProductID      CurrentYearValidity      CurrentYearCount   PreviousYearValidity   PreviousYearCount   PreviousTowYearsValidity  PreviousTwoYearCount
1           10/1/2015 to 20/12/2015        100          
1              NULL                         NULL         1/4/2014 to 31/12/2014       200                
1              NULL                         NULL             NULL                       NULL                   2/2/2013 to 20/9/2013        300

我希望结果在视图中。

请帮助。

编辑: 如果表只有值

 ProductID  ValidFrom   ValidTo     Count
----------------------------------------
 1           1/4/2014  31/12/2014     200
 1           2/2/2013  20/9/2013      300

然后结果应显示为

 ProductID      CurrentYearValidity      CurrentYearCount   PreviousYearValidity   PreviousYearCount   PreviousTowYearsValidity  PreviousTwoYearCount
1           NULL        NULL            1/4/2014 to 31/12/2014       200                2/2/2013 to 20/9/2013     300

@Giorgi Nakeuri在这种情况下,您的查询失败。 对于您的查询,结果是,

 ProductID      CurrentYearValidity      CurrentYearCount   PreviousYearValidity   PreviousYearCount   PreviousTowYearsValidity  PreviousTwoYearCount
1                1/4/2014 to 31/12/2014       200            2/2/2013 to 20/9/2013     300               NULL                   NULL

1 个答案:

答案 0 :(得分:0)

尝试:

DECLARE @t TABLE
    (
      ProductID INT ,
      ValidFrom DATE ,
      ValidTo DATE ,
      Count INT
    )
INSERT  INTO @t
VALUES  ( 1, '20150110', '20151220', 100 ),
        ( 1, '20140104', '20141231', 200 ),
        ( 1, '20130202', '20130920', 300 );
WITH    cte1
          AS ( SELECT   ProductID ,
                        CAST(ValidFrom AS NVARCHAR(10)) AS ValidFrom ,
                        ROW_NUMBER() OVER ( PARTITION BY ProductID ORDER BY ValidFrom DESC ) AS rn
               FROM     @t
             ),
        cte2
          AS ( SELECT   ProductID ,
                        CAST(ValidTo AS NVARCHAR(10)) AS ValidTo ,
                        ROW_NUMBER() OVER ( PARTITION BY ProductID ORDER BY ValidFrom DESC ) AS rn
               FROM     @t
             ),
        cte3
          AS ( SELECT   ProductID ,
                        Count ,
                        ROW_NUMBER() OVER ( PARTITION BY ProductID ORDER BY ValidFrom DESC ) AS rn
               FROM     @t
             )
    SELECT  p1.ProductID ,
            p1.[1] + ' to ' + p2.[1] AS CurrentYearValidity ,
            p3.[1] AS CurrentYearCount ,
            p1.[2] + ' to ' + p2.[2] AS PreviousYearValidity ,
            p3.[2] AS PreviousYearCount ,
            p1.[3] + ' to ' + p2.[3] AS PreviousTowYearsValidity ,
            p3.[3] AS PreviousTwoYearCount
    FROM    ( SELECT    *
              FROM      cte1 PIVOT( MAX(ValidFrom) FOR rn IN ( [1], [2], [3] ) ) p
            ) p1
            JOIN ( SELECT   *
                   FROM     cte2 PIVOT( MAX(ValidTo) FOR rn IN ( [1], [2], [3] ) ) p
                 ) p2 ON p2.ProductID = p1.ProductID
            JOIN ( SELECT   *
                   FROM     cte3 PIVOT( MAX(Count) FOR rn IN ( [1], [2], [3] ) ) p
                 ) p3 ON p3.ProductID = p2.ProductID

输出:

ProductID   CurrentYearValidity         CurrentYearCount    PreviousYearValidity        PreviousYearCount   PreviousTowYearsValidity    PreviousTwoYearCount
1           2015-01-10 to 2015-12-20    100                 2014-01-04 to 2014-12-31    200                 2013-02-02 to 2013-09-20    300