在 T-SQL 中旋转 table

Rotate table in T-SQL

我有一个 table,它在第一列中包含顺序日期和日期类型(CreatedOn 和 ClosedOn)。我需要使用 SELECT 我的 table.
中有 2 列(CreatedOn,ClosedOn) 我有这个:

| 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

但是没用。

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

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

这是在 SQL 服务器中使用 PIVOT 将行转置为列的典型案例:

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

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

;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