SQL如何将列转置为行

时间:2016-02-24 09:40:18

标签: sql sql-server database

我有这张表“概述”

+--------+---------+-------+-------+-----+-----+----+--------+
|fName   |shName   |project|task   |owner|hours|cmpt|modified|
+--------+---------+-------+-------+-----+-----+----+--------+
|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              

我希望将列拆分小时,cmpt,修改并重复每一行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

任何想法请如何制作?非常感谢你

2 个答案:

答案 0 :(得分:1)

可以通过unpivoting实现这里是一种方式

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 modifiedvarchar

答案 1 :(得分:1)

只需使用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

enter image description here

并注意当您对列进行UNPIVOT时,列必须是相同类型(这就是我首先投射它们的原因)。