2011-03-26 132 views
1

我需要採取一些查詢結果並將它們展平以獲取報表。轉換SQL查詢結果

DECLARE @randomTable table (ID int, OtherID int, Val varchar(max)) 

insert into @randomTable(ID, OtherID, Val) 
values (1, 100, 'Some Value 1'), (2, 100, 'Some Other 2'), 
     (3, 100, 'Some Value 3'), (4, 200, 'Some Other 4'), 
     (5, 200, 'Some Value 5'), (6, 300, 'Some Other 6'), 
     (7, 300, 'Some Value 7'), (8, 300, 'Some Other 8'), 
     (9, 400, 'Some Value 9'), (10, 500, 'Some Other 10')    

select OtherID, Val from @randomTable 

結果:

-- 100 | Some Value 1 
-- 100 | Some Other 2 
-- 100 | Some Value 3 
-- 200 | Some Other 4 
-- 200 | Some Value 5 
-- 300 | Some Other 6 
-- 300 | Some Value 7 
-- 300 | Some Other 8 
-- 400 | Some Value 9 
-- 500 | Some Other 10 

是否有一個SQL的方式來改變這種作爲選擇:

-- 100 | Some Value 1 | Some Other 2 | Some Value 3 
-- 200 | Some Other 4 | Some Value 5 
-- 300 | Some Other 6 | Some Value 7 | Some Other 8 
-- 400 | Some Value 9 
-- 500 | Some Other 10 

注意:上面就是一個例子。我的真實數據不是靜態的。此外,在我的真實數據中,OtherID是一個字符串值,Val值是以varbinary存儲的圖像。

我當然要限制我將允許的列數。我想最多5(在這之後,我很好,失去了額外的行)。

有沒有辦法做到這一點?

回答

4
;WITH cte 
    AS (SELECT OtherID, 
       Val, 
       ROW_NUMBER() OVER (PARTITION BY OtherID ORDER BY (SELECT 0)) rn 
     FROM @randomTable) 
SELECT OtherID, 
     [1], 
     [2], 
     [3], 
     [4], 
     [5] 
FROM cte PIVOT(MAX(Val) FOR rn IN ([1], [2], [3], [4], [5])) AS PivotTable; 

提供一些解釋SELECT * FROM cte將返回以下。

OtherID  Val     rn 
----------- -------------------- --- 
100   Some Value 1   1 
100   Some Other 2   2 
100   Some Value 3   3 
200   Some Other 4   1 
200   Some Value 5   2 
300   Some Other 6   1 
300   Some Value 7   2 
300   Some Other 8   3 
400   Some Value 9   1 
500   Some Other 10  1 

我已經加入了row_number列給一些在PIVOT使用。請注意,每OtherID,rn組合有零或一行。 PIVOT聲明相當於以下內容。

SELECT OtherID, 
     MAX(CASE WHEN rn=1 THEN Val END) AS [1], 
     MAX(CASE WHEN rn=2 THEN Val END) AS [2], 
     MAX(CASE WHEN rn=3 THEN Val END) AS [3], 
     MAX(CASE WHEN rn=4 THEN Val END) AS [4], 
     MAX(CASE WHEN rn=5 THEN Val END) AS [5] 
FROM cte 
GROUP BY OtherID /*You want one row per OtherID */ 
+0

這正是我所需要的!謝謝馬丁,你很樂意幫助我解決這個問題! – Vaccano 2011-03-27 03:51:09

+1

Martin,非常聰明的使用rn分區! – 2011-03-27 04:18:40

2

林不知道,如果你想樞轉到列或連接結果轉換成一列(報告)。

如果您正在尋找動態數據透視表,請查看此處的文章:link以及其後的評論。如果你能夠限制主軸所涉及的列,你可以使用pivot操作符(如前所述)並獲得更好的性能。

如果您希望將行連接到列,請查看下面的查詢。利用XML PATH確實會對特殊字符(< &等)產生一些影響,因此如果這適用於您的情況,請回傳,我們可以擴展此簡單示例。

-- if you have normalized type table use it instead of this cte 
    ;with c_distinct (OtherId) 
    as  ( select distinct OtherId 
       from @randomTable 
      ) 
    select OtherId, 
      stuff(c, 1, 2, '') 
    from c_distinct cd 
    cross 
    apply ( select '| ' + Val 
       from @randomTable rt 
       where cd.OtherId = rt.OtherId 
       for xml path('') 
      ) d(c)