你所要做的是一個完整的數據調換您的當前數據的列變爲行,你的行變爲列,這可以分兩步來完成。首先,應用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