SQL如何将列转换为行
我有这张“概述”表 我想转换列hours、cmpt、modified,并每行重复3次,我的表就是这样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
|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
。。。