SQL如何将列转换为行

SQL如何将列转换为行,sql,sql-server,database,Sql,Sql Server,Database,我有这张“概述”表 我想转换列hours、cmpt、modified,并每行重复3次,我的表就是这样 |fName |shName|project|task |owner| h/c/m |val +--------+------+-------+-------+-----+--------+----------+ |Taskday1|IBM |Website|develop|sam |hours |5 |Taskday1|IBM |Website|develop|sa

我有这张“概述”表

我想转换列hours、cmpt、modified,并每行重复3次,我的表就是这样

|fName   |shName|project|task   |owner| h/c/m  |val
+--------+------+-------+-------+-----+--------+----------+
|Taskday1|IBM   |Website|develop|sam  |hours   |5  
|Taskday1|IBM   |Website|develop|sam  |cmpt    |25  
|Taskday1|IBM   |Website|develop|sam  |modified|2/2/2016               
|Taskday1|IBM   |website|test   |sam  |hours   |7          
|Taskday1|IBM   |website|test   |sam  |cmpt    |20             
|Taskday1|IBM   |website|test   |sam  |modified|2/2/2016
|Taskday1|IBM   |support|design |ivan |hours   |2
|Taskday1|IBM   |support|design |ivan |cmpt    |7
|Taskday1|IBM   |support|design |ivan |modified|2/2/2016
|Taskday2|DELL  |android|config |peter|hours   |9
|Taskday2|DELL  |android|config |peter|cmpt    |30
|Taskday2|DELL  |android|config |peter|modified|3/2/2016
|Taskday2|IBM   |Website|develop|sam  |hours   |9
|Taskday2|IBM   |Website|develop|sam  |cmpt    |45
|Taskday2|IBM   |Website|develop|sam  |modified|3/2/2016

有什么想法吗?怎么做?非常感谢

可以通过
取消激励
来实现

SELECT fName,
       shName,
       project,
       task,
       owner,
       [h/c/m],
       value
FROM   yourtable 
       CROSS apply (VALUES ('hours',hours),
                           ('cmpt',cmpt),
                           ('modified',modified)) cs([h/c/m], value) 

注意:如果
modified
Date
数据类型,那么您需要
cast
修改后的
转换为
varchar

可以通过
取消激励来实现

SELECT fName,
       shName,
       project,
       task,
       owner,
       [h/c/m],
       value
FROM   yourtable 
       CROSS apply (VALUES ('hours',hours),
                           ('cmpt',cmpt),
                           ('modified',modified)) cs([h/c/m], value) 

注意:如果
modified
属于
Date
数据类型,则需要
cast
修改后的
转换为
varchar

只需使用
UNPIVOT
功能:

DECLARE @DataSoruce TABLE
(   
    [fName] VARCHAR(12)
   ,[shName] VARCHAR(8)
   ,[proiject] VARCHAR(8)
   ,[task] VARCHAR(8)
   ,[owner] VARCHAR(8)
   ,[hours] TINYINT
   ,[cmpt] INT
   ,[modified] VARCHAR(8)
);

INSERT INTO @DataSoruce ([fName], [shName], [proiject], [task], [owner], [hours], [cmpt], [modified])
VALUES   ('Taskday1', 'IBM', 'Website', 'develop', 'sam', '5', '25', '2/2/2016')
        ,('Taskday1', 'IBM', 'website', 'test', 'sam', '7', '20', '2/2/2016')
        ,('Taskday1', 'IBM', 'support', 'design ', 'ivan ', '2', '7', '2/2/2016')
        ,('Taskday2', 'DELL', 'android', 'config ', 'peter', '9', '30', '3/2/2016')
        ,('Taskday2', 'IBM', 'Website', 'develop', 'sam', '9', '45', '3/2/2016');

SELECT [fName]
      ,[shName]
      ,[proiject]
      ,[task]
      ,[owner]
      ,[h/c/m]
      ,[Val]
FROM 
(
    SELECT [fName]
          ,[shName]
          ,[proiject]
          ,[task]
          ,[owner]
          ,CAST([hours] AS VARCHAR(8)) AS [hours]
          ,CAST([cmpt] AS VARCHAR(8)) AS [cmpt]
          ,CAST([modified] AS VARCHAR(8)) AS [modified]
    FROM @DataSoruce
) DS
UNPIVOT
(
    [Val] FOR [h/c/m]  IN ([hours], [cmpt], [modified])
) UNPVT


请注意,在对列执行
UNPIVOT
操作时,列必须是相同的类型(这就是我首先强制转换它们的原因)。

只需使用
UNPIVOT
功能:

DECLARE @DataSoruce TABLE
(   
    [fName] VARCHAR(12)
   ,[shName] VARCHAR(8)
   ,[proiject] VARCHAR(8)
   ,[task] VARCHAR(8)
   ,[owner] VARCHAR(8)
   ,[hours] TINYINT
   ,[cmpt] INT
   ,[modified] VARCHAR(8)
);

INSERT INTO @DataSoruce ([fName], [shName], [proiject], [task], [owner], [hours], [cmpt], [modified])
VALUES   ('Taskday1', 'IBM', 'Website', 'develop', 'sam', '5', '25', '2/2/2016')
        ,('Taskday1', 'IBM', 'website', 'test', 'sam', '7', '20', '2/2/2016')
        ,('Taskday1', 'IBM', 'support', 'design ', 'ivan ', '2', '7', '2/2/2016')
        ,('Taskday2', 'DELL', 'android', 'config ', 'peter', '9', '30', '3/2/2016')
        ,('Taskday2', 'IBM', 'Website', 'develop', 'sam', '9', '45', '3/2/2016');

SELECT [fName]
      ,[shName]
      ,[proiject]
      ,[task]
      ,[owner]
      ,[h/c/m]
      ,[Val]
FROM 
(
    SELECT [fName]
          ,[shName]
          ,[proiject]
          ,[task]
          ,[owner]
          ,CAST([hours] AS VARCHAR(8)) AS [hours]
          ,CAST([cmpt] AS VARCHAR(8)) AS [cmpt]
          ,CAST([modified] AS VARCHAR(8)) AS [modified]
    FROM @DataSoruce
) DS
UNPIVOT
(
    [Val] FOR [h/c/m]  IN ([hours], [cmpt], [modified])
) UNPVT


请注意,当您对列执行
UNPIVOT
操作时,列必须是相同的类型(这就是为什么我首先强制转换它们)。

但是为什么?这似乎毫无意义。是否要将所有人都联合起来,为每个h/c/m选择一个
,但为什么?这似乎毫无意义。对每个h/c/m使用一个
select
,对所有人执行
UNION
。。。