2010-04-12 54 views
1

我正在尋找將行轉換爲列的最高性能方式。我有一個要求輸出固定寬度和分隔格式的數據庫的內容(下面不是實際的模式,但概念是相似的)。下面的FOR XML PATH查詢爲我提供了我想要的結果,但是在處理除少量數據之外的其他任何事情時,可能需要一段時間。t-sql最高效的行列? crosstab for xml path,pivot

select orderid 
    ,REPLACE(( SELECT ' ' + CAST(ProductId as varchar) 
     FROM _details d 
     WHERE d.OrderId = o.OrderId 
     ORDER BY d.OrderId,d.DetailId 
     FOR XML PATH('') 
    ),' ','') as Products 
from _orders o 

我已經看過了數據透視表,但我發現的大多數示例都是聚合信息。我只想合併子行並將它們粘貼到父項上。

我還應該指出,我不需要處理列名稱,因爲子行的輸出將是固定寬度的字符串或分隔字符串。

例如,給出下面的表格:

OrderId  CustomerId 
----------- ----------- 
1   1 
2   2 
3   3 

DetailId OrderId  ProductId 
----------- ----------- ----------- 
1   1   100 
2   1   158 
3   1   234 
4   2   125 
5   3   101 
6   3   105 
7   3   212 
8   3   250 

一個爲了我需要輸出:

orderid  Products 
----------- ----------------------- 
1    100 158 234 
2    125 
3    101 105 212 250 

orderid  Products 
----------- ----------------------- 
1   100|158|234 
2   125 
3   101|105|212|250 

想法或建議?我正在使用SQL Server 2k5。

設置示例:

create table _orders (
    OrderId int identity(1,1) primary key nonclustered 
    ,CustomerId int 
) 

create table _details (
    DetailId int identity(1,1) primary key nonclustered 
    ,OrderId int 
    ,ProductId int 
) 

insert into _orders (CustomerId) 
select 1 
union select 2 
union select 3 

insert into _details (OrderId,ProductId) 
select 1,100 
union select 1,158 
union select 1,234 
union select 2,125 
union select 3,105 
union select 3,101 
union select 3,212 
union select 3,250 

CREATE CLUSTERED INDEX IX_CL__orders on _orders(OrderId) 
CREATE NONCLUSTERED INDEX IX_NCL__orders on _orders(OrderId) 
INCLUDE (CustomerId) 

CREATE CLUSTERED INDEX IX_CL_details on _details(OrderId) 
CREATE NONCLUSTERED INDEX IX_NCL_details on _details(OrderId) 
INCLUDE (DetailId,ProductId) 

使用FOR XML PATH:

select orderid 
    ,REPLACE(( SELECT ' ' + CAST(ProductId as varchar) 
     FROM _details d 
     WHERE d.OrderId = o.OrderId 
     ORDER BY d.OrderId,d.DetailId 
     FOR XML PATH('') 
    ),' ','') as Products 
from _orders o 

,輸出我想要的東西,但是對大量數據的速度很慢。其中一個子表超過200萬行,將處理時間推遲到〜4小時。

orderid  Products 
----------- ----------------------- 
1    100 158 234 
2    125 
3    101 105 212 250 

回答

0

根據定義,PIVOT將以某種方式進行聚合,因爲您可以有多個具有相同透視鍵列的行。如果你沒有多行,那很好 - 但你仍然需要選擇一個聚合運算符(MIN,MAX,SUM)。

但是FOR XML PATH構造更適合於多行值到單字符串「透視」操作。我不確定你爲什麼表現不好。你有什麼指標在桌子上?你的執行計劃是什麼樣子的?

+0

在主鍵列上有一個聚簇索引,在主鍵列上有一個非聚簇索引,並且包含表中的每個其他列 – ajberry 2010-04-13 13:50:03

+0

@ajberry - 在詳細信息表上,您是否具有OrderId上的鍵,DetailId其中包括ProductId? – 2010-04-13 14:04:11

+0

我添加了上面示例設置下通常在表格中的索引。我需要重新檢查實際表格上的索引,這裏可能會進行一些調整。 – ajberry 2010-04-13 14:51:09