在SQL Server中将列转换为行

在SQL Server中将列转换为行,sql,sql-server,sql-server-2008,tsql,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_Typ

我有一个名为
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  
测试数据 查询 结果 更新 对于带下划线或不带下划线的列名,可以在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
测试数据 查询 结果 更新 对于带下划线或不带下划线的列名,可以在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

除了
UNPIVOT
和使用
UNION ALL
之外的另一个选项是
交叉应用

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);

sqlfiddle演示。

除了
UNPIVOT
和使用
UNION ALL
之外的另一个选项是
交叉应用

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);

sqlfiddle和演示。

DT\u类型和日期\u历史列从何而来?它们是同一个表的一部分吗?DT_Type和Dates_Hist列来自哪里?它们是同一个表的一部分吗?谢谢,阿里,只有一个问题,我们怎么做才能让自定义值或名称为DT_类型,就像上面的例子一样,我希望cntr_date为cntr,appv_date为appvas,只要格式相同,它就可以工作,但如果我们给alias,它就不能正常工作了?我刚刚完全按照你的要求做了,您询问的别名是什么?Op的意思是,即使在本例中,
DT_Type
的值是他/她想要的值,这只是因为列名有特定的格式,但他/她不能给那些他/她想要的值wanted@peter好,好,,好的,只要一个列名有一个欠字符,它就会在这个特定的查询中将列名的第一部分拉到下划线之前。谢谢你,阿里,只有一个问题,我们可以做什么来让自定义值或名称为DT_类型,就像上面的示例中一样,我希望cntr_date是cntr,appv_date是appvas,只要格式相同,它就可以工作,但如果我们给alias,它就不能正常工作?我刚刚完全按照你的要求做了,你问的是什么别名?Op是说,即使在这种情况下,
DT_Type
的值是他/她想要的值,这只是因为列名有特定的格式,但他/她不能给那些如果他/她wanted@peter好的,好的,只要一个列名有一个底字符,它就会用这个特定的查询将列名的第一部分拉到下划线之前。
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);