質問

私は列に行を有効にする最もパフォーマンスの方法を探しています。固定幅および区切り形式の両方で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構築物は、より優れた複数行値のための単一のストリング列「ピボット」操作である。

あなたがうまく行っていない理由私はわかりません。あなたは、テーブルの上にどのようなインデックスを持っていますか? ?

のようなあなたの実行計画を見て何をして
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top