我正在寻找将行转换为列的最高效方法。我需要以固定宽度和分隔格式输出数据库的内容(不是下面的实际模式,但概念相似)。下面的 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
我已经查看了 pivot 但我发现的大多数示例都是聚合信息。我只想合并子行并将它们附加到父行上。
我还应该指出,我也不需要处理列名,因为子行的输出要么是固定宽度的字符串,要么是分隔的字符串。
例如,给定下表:
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 路径:
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