2013-03-06 58 views
2

我需要轉動在SQL Server中的表結構如下:樞軸或轉在SQL Server中的表不進行分組BY

CREATE TABLE table1 (
    ColumnNumber int, 
    RowNumber int, 
    CellData nvarchar(50) 
) 

INSERT INTO table1 VALUES 
(1, 1, 'Orange'), 
(2, 1, 'Apple'), 
(3, 1, 'Banana'), 
(1, 2, 'Grape'), 
(2, 2, 'Corn'), 
(3, 2, 'Lemon'), 
(1, 3, 'Tomato'), 
(2, 3, 'Lettuce'), 
(3, 3, 'Onion') 

而我需要的結果表看起來像這樣:

enter image description here

因此,ColumnNumber行中的單元現在是結果表的列名稱。最難的部分是不同列數的數量是可變的(所以現在,我們有3列數,但明天可能會有6或10)。

我一直在尋找PIVOT函數,但所有的例子都包含GROUP BY,正如你在這裏看到的,我需要更多的東西,像一個「轉置」excel函數。

謝謝!

+0

構建SQL動態。是的,這很醜。但是,這是必需的,因爲每個查詢都具有與數據無關的固定形狀(例如已知列名稱)。網上有很多例子,搜索「動態樞軸」 - 例如http://stackoverflow.com/questions/10404348/sql-server-dynamic-pivot-query – 2013-03-06 23:16:28

+0

也http://stackoverflow.com/questions/12430512/dynamic-pivot-table-in-sql-server?rq=1 ,http://stackoverflow.com/questions/1984306/sql-server-pivot-column-data?rq=1等 – 2013-03-06 23:22:25

回答

6

這可以使用PIVOT函數完成。 GROUP BY將工作,因爲你有一個指標,使每一行不同。對於您的數據,該指標是rowNumber列。

如果您有一定數量的列,那麼您將需要使用靜態數據透視表對其進行硬編碼。該代碼將類似於以下內容:

select [1], [2], [3] 
from 
(
    select colNumber, RowNumber, CellData 
    from yourtable 
) src 
pivot 
(
    max(CellData) 
    for colnumber in ([1], [2], [3]) 
) piv; 

請參閱SQL Fiddle with Demo

就你而言,你表示你將有不明數量的列。如果這是你的情況,那麼你將需要使用動態sql來建立要轉移的列的列表。我演示了靜態版本,因爲它更容易將代碼轉換爲動態SQL。

動態sql版本的關鍵是獲取通過查詢您的表和創建列名稱字符串完成列的列表。這是使用FOR XML PATH完成:

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(colNumber) 
        from yourtable 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

這個列表加入到您生成的查詢字符串,最終的代碼則是:

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(colNumber) 
        from yourtable 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT ' + @cols + ' 
      from 
      (
       select colNumber, rowNumber, CellData 
       from yourtable 
      ) x 
      pivot 
      (
       min(CellData) 
       for colNumber in (' + @cols + ') 
      ) p ' 

execute(@query) 

SQL Fiddle with Demo

均可以得到結果:

|  1 |  2 |  3 | 
----------------------------- 
| Orange | Apple | Banana | 
| Grape | Corn | Lemon | 
| Tomato | Lettuce | Onion | 
+0

@pst我不明白你的意見。 bluefeet回答了另一個關鍵問題。如果你注意到,他們*真的*似乎喜歡這類問題,並提供全面,詳細和正確的答案。 – billinkc 2013-03-06 23:30:40

+0

@bluefeet雖然,爲什麼MIN在這裏選擇vs MAX在其他?只是每日偏好還是會影響到語義? – 2013-03-06 23:35:43

+0

@pst由於正在對字符串進行聚合,因此可以使用'min'或'max'。他們都會給出相同的結果。 – Taryn 2013-03-06 23:36:42