在T-SQL中旋转表

时间:2017-03-28 14:30:04

标签: sql sql-server tsql pivot

我有一个表,其中包含第一列中的连续日期和日期类型(CreatedOn和ClosedOn)。我需要在我的表中使用具有2列(CreatedOn,ClosedOn)的SELECT 我有这个:

| Date       | ColumnName |
|------------|------------|
| 2017-01-01 | ClosedOn   |
| 2017-01-02 | CreatedOn  |
| 2017-01-03 | ClosedOn   |
| 2017-01-04 | CreatedOn  |

我需要得到这个:

| CreatedOn  | ClosedOn   |
|------------|------------|
| NULL       | 2017-01-01 |
| 2017-01-02 | 2017-01-03 |
| 2017-01-04 | NULL       |

我试过这个:

SELECT
    CASE [ColumnName]
        WHEN 'CreatedOn' THEN [Date]
        ELSE NULL
    END,
    CASE [ColumnName]
        WHEN 'ClosedOn' THEN [Date]
        ELSE NULL
    END
FROM #Temp

但它不起作用。

3 个答案:

答案 0 :(得分:1)

这是在SQL Server中使用PIVOT,将行转换为列的典型案例:

select *
from table1 
pivot (max(colname) for colname in (ClosedOn, CreatedOn)) p
order by date

enter image description here

答案 1 :(得分:1)

试试这个并希望它有所帮助。您可能需要对其进行测试并根据需要进行修改。但是,如果我的理解是正确的,逻辑应足以建立起来。

;WITH cte_TestData(Date,ColumnName) AS
(
SELECT '2017-01-01','ClosedOn ' UNION ALL
SELECT '2017-01-02','CreatedOn' UNION ALL
SELECT '2017-01-03','ClosedOn ' UNION ALL
SELECT '2017-01-04','CreatedOn'
)
,cte_PreserveSeq AS
(
SELECT ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS SeqID,Date,ColumnName
FROM cte_TestData
)
,cte_PreResult AS
(
SELECT *
    ,LEAD  (ColumnName, 1,0) OVER (ORDER BY SeqID) AS NextColumnName
    ,LEAD  (Date, 1,0) OVER (ORDER BY SeqID) AS NextDate
    ,LAG  (ColumnName, 1,0) OVER (ORDER BY SeqID) AS PreviousColumnName
    ,LAG  (Date, 1,0) OVER (ORDER BY SeqID) AS PreviousDate
FROM cte_PreserveSeq
)
SELECT DISTINCT
    CASE 
        WHEN ColumnName = 'CreatedOn' AND NextColumnName = 'ClosedOn' THEN DATE
        WHEN ColumnName = 'ClosedOn' AND PreviousColumnName = 'CreatedOn' THEN PreviousDate
        WHEN ColumnName = 'CreatedOn' THEN DATE
        ELSE NULL
        END AS CreatedOn,
    CASE 
        WHEN ColumnName = 'CreatedOn' AND NextColumnName = 'ClosedOn' THEN NextDate
        WHEN ColumnName = 'ClosedOn' THEN DATE
        ELSE NULL
        END AS ClosedOn
FROM cte_PreResult

答案 2 :(得分:0)

我假设你有其他专栏,所以让我们这样做

select A1.OtherColumn, A1.[Date], A2.Date
from #Temp A1
full outer join #Temp A2
  on A1.OtherColumn = A2.OtherColumn
  and A1.ColumnName = 'CreatedOn'
  and A2.ColumnName = 'ClosedOn'

编辑:如果没有其他列,请尝试

with MyData as
(
select [Date], ColumnName , row_number() over (order by [Date], ColumnName desc) as rn
from #Temp
)
select M1.[Date], M2.[Date]
from MyData M1
full outer join MyData M2
  on M2.rn = M1.rn + 1
  and mod(M1.rn, 2) = 1