你所要做的是一个完整的数据调换您的当前数据的列变为行,你的行变为列,这可以分两步来完成。首先,应用UNPIVOT功能转换的Conv1
,Conv2
,等你当前列成行,那么在应用旋转功能的data1
,data2
转换成列。
此前试图编写查询的动态版本,我总是用一个静态的版本启动,以便能得到正确的逻辑,然后转换为动态SQL。为了产生新的列名Col1
,Col2
等查询数据时,我会用一个窗口函数像row_number()
,这会为你要转的每一行数据的唯一序列。
的UNPIVOT代码将类似于:
;with cte as
(
select Conv1, Conv2, Conv3,
row_number() over(order by conv1) seq
from dbo.yourtable
)
select *
from
(
select Conv, value,
col = 'Col'+cast(seq as varchar(50))
from cte
unpivot
(
value for Conv in (Conv1, Conv2, Conv3)
) unpiv
) src;
见SQL Fiddle with Demo。这些数据将是这样的:
| CONV | VALUE | COL |
|-------|-------|------|
| Conv1 | data1 | Col1 |
| Conv2 | data2 | Col1 |
| Conv3 | data3 | Col1 |
| Conv1 | data1 | Col2 |
| Conv2 | data2 | Col2 |
| Conv3 | data3 | Col2 |
你会发现,你现在必须为每个Conv1
多行和你有一个新的列使用row_number()
来创建新的列名。现在您可以使用PIVOT完成数据的旋转:
;with cte as
(
select Conv1, Conv2, Conv3,
row_number() over(order by conv1) seq
from dbo.yourtable
)
select Conv, Col1, Col2, Col3
from
(
select Conv, value,
col = 'Col'+cast(seq as varchar(50))
from cte
unpivot
(
value for Conv in (Conv1, Conv2, Conv3)
) unpiv
) src
pivot
(
max(value)
for col in (Col1, Col2, Col3)
) piv;
请参阅SQL Fiddle with Demo。这将完全转换您的当前数据到您的最终结果。对于你的情况你说你需要一个动态解决方案,所以你将需要使用动态SQL。这将涉及到越来越需要被逆转置列名,然后将新列的列表为枢轴:
DECLARE @colsUnpivot AS NVARCHAR(MAX),
@colsPivot AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @colsUnpivot = STUFF((SELECT ','+ quotename(c.name)
from sys.tables t
inner join sys.columns c
on t.object_id = c.object_id
where t.name = 'yourtable'
group by c.name, c.column_id
order by c.column_id
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
select @colsPivot = STUFF((SELECT ','+ quotename('Col'+cast(seq as varchar(10)))
from
(
select row_number() over(order by conv1) seq
from dbo.yourtable
) d
group by seq
order by seq
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query
= ';with cte as
(
select Conv1, Conv2, Conv3,
row_number() over(order by conv1) seq
from dbo.yourtable
)
select Conv, '[email protected]+'
from
(
select Conv, value,
col = ''Col''+cast(seq as varchar(50))
from cte
unpivot
(
value for Conv in ('[email protected]+')
) unpiv
) src
pivot
(
max(value)
for col in ('[email protected]+')
) piv'
execute sp_executesql @query;
见SQL Fiddle with Demo。这两个给出最终结果:
| CONV | COL1 | COL2 | COL3 |
|-------|-------|-------|-------|
| Conv1 | data1 | data1 | data1 |
| Conv2 | data2 | data2 | data2 |
| Conv3 | data3 | data3 | data3 |
这是执行动态旋转的方式: http://stackoverflow.com/a/11985946/3503205 – Ryx5
你尝试过:HTTP:// stackoverflow.com/questions/15091330/sql-server-convert-columns-to-rows][1] [1]:http://stackoverflow.com/questions/15091330/sql-server-convert-columns- to-rows – lyosha
我不明白我会用@代替@ Ryx5注释中的min(choice),或者@lyosha注释中的max(val)。或者对于这个问题真的是'Pivot'部分的内容。在所有示例中,我都看到原始表格中包含具有特定内容的列,在我的案例中,这些列基本上包含几乎相同类型的数据,但对它们没有真正的区别特征。 – shadonar