T-SQLの列に最も効率的な行? XMLパスのクロス集計、ピボット
-
26-09-2019 - |
質問
私は列に行を有効にする最もパフォーマンスの方法を探しています。固定幅および区切り形式の両方でIは出力する必要DBの内容を有する(以下ではない実際のスキーマが、概念は同様です)。 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
私は、ピボットを見てきましたが、私が見つけた例のほとんどは、情報を集約しています。私は親に子行を結合し、それらをタックしたい。
私も指摘しなければならない私は、列名のいずれか子行の出力は、どちらか固定幅の文字列または区切り文字列になりますので、対処する必要はありません。
は、例えば、以下の表に与えられた
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)
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
私が欲しいものを出力は、しかし、大量のデータのために非常に遅いです。子テーブルの1つは、〜4時間から処理時間を押して、200万人以上の行です。
orderid Products
----------- -----------------------
1 100 158 234
2 125
3 101 105 212 250
解決
定義でPIVOTを使用すると、同じピボットキー列を持つ複数の行を持つことができるので、何らかの方法で集計しているつもりです。あなたは罰金のことを、複数の行を持っていない場合 - あなたはまだ集計演算子(MIN、MAX、SUM)を選択する必要があります。
。しかしFOR XML PATH
構築物は、より優れた複数行値のための単一のストリング列「ピボット」操作である。
私はわかりません。あなたは、テーブルの上にどのようなインデックスを持っていますか? ?
のようなあなたの実行計画を見て何をして所属していません StackOverflow