在SQL Server中将列转换为行

时间:2014-08-13 19:05:12

标签: sql sql-server sql-server-2008 tsql

我有一个名为Dateinfo的表格,数据如下所示:

Cntr_Date   Appv_Date   Prop_Date     ID    Lvl
------------------------------------------------
2014-04-11  2014-03-21  2014-07-29    4867  1
2014-04-21  2014-04-29  2014-04-21    4867  1a

我希望我的输出看起来像这样:

ID      Lvl    DT_Type      Dates_Hist
---------------------------------------
4867    1      Cntr         2014-04-11
4867    1      Appv         2014-03-21
4867    1      Prop         2014-07-29
4867    1a     Cntr         2014-04-21
4867    1a     Appv         2014-04-29
4867    1a     Prop         2014-04-21  

2 个答案:

答案 0 :(得分:2)

测试数据

DECLARE @TABLE 
   TABLE(Cntr_Date DATE, Appv_Date DATE, Prop_Date DATE, ID INT, Lvl VARCHAR(10))

INSERT INTO @TABLE VALUES 
('2014-04-11','2014-03-21','2014-07-29',4867,'1'),
('2014-04-21','2014-04-29','2014-04-21',4867,'1a')

查询

SELECT  ID
      , Lvl
      , LEFT(DT_Type, CHARINDEX('_',DT_Type)-1) AS DT_Type 
      , Date_Hist
FROM @TABLE
 UNPIVOT ( Date_Hist FOR 
           DT_Type IN (Cntr_Date, Appv_Date, Prop_Date) 
         ) UP

结果

╔══════╦═════╦═════════╦════════════╗
║  ID  ║ Lvl ║ DT_Type ║ Date_Hist  ║
╠══════╬═════╬═════════╬════════════╣
║ 4867 ║ 1   ║ Cntr    ║ 2014-04-11 ║
║ 4867 ║ 1   ║ Appv    ║ 2014-03-21 ║
║ 4867 ║ 1   ║ Prop    ║ 2014-07-29 ║
║ 4867 ║ 1a  ║ Cntr    ║ 2014-04-21 ║
║ 4867 ║ 1a  ║ Appv    ║ 2014-04-29 ║
║ 4867 ║ 1a  ║ Prop    ║ 2014-04-21 ║
╚══════╩═════╩═════════╩════════════╝

更新

对于包含或不包含Underscore的列名,您可以对case语句中的值进行硬编码,如下所示

SELECT  ID
      , Lvl
      , CASE DT_Type
          WHEN 'Cntr_Date' THEN 'Cntr' 
          WHEN 'Appv_Date' THEN 'Appv'
          WHEN 'Prop_Date' THEN 'Prop'
         END AS DT_Type
      , Date_Hist
FROM @TABLE
 UNPIVOT ( Date_Hist FOR 
           DT_Type IN (Cntr_Date, Appv_Date, Prop_Date) 
         ) UP

答案 1 :(得分:2)

除了UNPIVOT并使用UNION ALL之外的另一个选项是CROSS APPLY

SELECT  t.id,
        t.Lvl,
        x.*
FROM YourTable t
CROSS APPLY 
(
    VALUES
        ('Cntr', t.Cntr_Date),
        ('Appv', t.Appv_Date),
        ('Prop', t.Prop_Date)
) x (DT_Type, Dates_Hist);

Here is一个带有演示的方形小说。