2014-04-08 15 views
0

我有一個動態生成的表,我需要有所有列變爲行變化列行

所以我的表看起來像這樣

Conv1 | Conv2 | ... 
data1 | data2 | ... 
data1 | data2 | ... 
data1 | data2 | ... 
... | ... | ... 

,因爲它是動態的,我不知道到底有多少行/列沒有運行Select count(*)或類似的東西。

基本上我想要上表中可以改變這個

data1 | data1 | data1 | ... 
data2 | data2 | data2 | ... 
data3 | data3 | data3 | ... 
data4 | data4 | data4 | ... 

我看着使用Pivot但是我不知道我怎麼會用它在這種情況下。

我正在使用SQL Server 2008 R2

任何幫助將不勝感激。讓我知道你是否需要更多信息。

謝謝。

--update

這裏是一個與「轉化」項目作爲列名的當前表結構。

Conv1 | Conv2 | Conv3 | ... 
data1 | data2 | data3 | ... 
data1 | data2 | data3 | ... 
data1 | data2 | data3 | ... 
... | ... | ... | ... 

這裏的「數據」作品是varchar(250)

考慮數據會話(CONV1)的存儲庫和行是一系列的問題和答覆。 因爲我在與我的工作是什麼性質不知道該「數據」的內容是一個問題,這是一個響應。

這就是我想要的結果看起來像:

 Col1 | Col2 | Col3 | ... 
Conv1 | data1 | data1 | data1 | ... 
Conv2 | data2 | data2 | data2 | ... 
Conv3 | data3 | data3 | data3 | ... 
Conv4 | data4 | data4 | data4 | ... 

如果這仍然沒有足夠的信息讓我知道,我會看看還有什麼我可以提供。

+0

這是執行動態旋轉的方式: http://stackoverflow.com/a/11985946/3503205 – Ryx5

+0

你嘗試過: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

+0

我不明白我會用@代替@ Ryx5註釋中的min(choice),或者@lyosha註釋中的max(val)。或者對於這個問題真的是'Pivot'部分的內容。在所有示例中,我都看到原始表格中包含具有特定內容的列,在我的案例中,這些列基本上包含幾乎相同類型的數據,但對它們沒有真正的區別特徵。 – shadonar

回答

1

你所要做的是一個完整的數據調換您的當前數據的列變爲行,你的行變爲列,這可以分兩步來完成。首先,應用UNPIVOT功能轉換的Conv1Conv2,等你當前列成行,那麼在應用旋轉功能的data1data2轉換成列。

此前試圖編寫查詢的動態版本,我總是用一個靜態的版本啓動,以便能得到正確的邏輯,然後轉換爲動態SQL。爲了產生新的列名Col1Col2等查詢數據時,我會用一個窗口函數像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 |