Frage

Ich bin für die performante Art und Weise Zeilen in Spalten zu drehen. Ich habe eine Verpflichtung zur Ausgabe der Inhalte des db (nicht unbedingt Schemas unten, sondern Konzept ist ähnlich) sowohl in fester Breite und begrenzt Formate. Die unter FOR XML PATH-Abfrage gibt mir das Ergebnis, das ich will, aber wenn sie mit etwas anderes als kleine Datenmengen zu tun, kann eine Weile dauern.

 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

Ich habe an einem Dreh aussah, aber die meisten Beispiele habe ich kumulieren Informationen gefunden. Ich will nur die untergeordneten Zeilen kombinieren und sie auf die Eltern heften.

Ich sollte auch ich mit den Spaltennamen, da der Ausgang entweder zu befassen brauchen nicht darauf aus den untergeordneten Zeilen entweder eine Breite Zeichenfolge oder eine Zeichenfolge mit Trennzeichen festgelegt werden.

Zum Beispiel der folgenden Tabellen angegeben:

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

für einen Auftrag muss ich Ausgabe:

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

oder

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

Die Gedanken oder Anregungen? Ich bin mit SQL Server 2k5.

Beispiel Setup:

   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)

mit 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

das gibt, was ich will, ist jedoch sehr langsam für große Datenmengen. Einer der untergeordneten Tabellen ist über 2 Millionen Zeilen, um ca. 4 Stunden, um die Bearbeitungszeit drücken.

orderid     Products
----------- -----------------------
1             100  158  234
2             125
3             101  105  212  250
War es hilfreich?

Lösung

Durch die Definition einer PIVOT ist zu haben, in irgendeiner Weise zu aggregieren, da Sie mehrere Zeilen mit den gleichen Drehschlüsselspalten haben. Wenn Sie nicht über mehrere Zeilen, ist das in Ordnung -. Aber immer noch ein Aggregat Operator (MIN, MAX, SUM)

wählen müssen

Aber das FOR XML PATH Konstrukt ist besser für die mehrreihigen-Werte zu Single-String-Spalte "Pivot" -Betrieb.

Ich bin nicht sicher, warum sind Sie nicht gut ab. Welche Indizes haben Sie auf den Tischen? Wie sieht Ihre Ausführungsplan aus?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top