Domanda

Sto cercando il modo più performante per trasformare righe in colonne. Ho un requisito uscita il contenuto del db (non effettivo schema seguente, ma il concetto è simile) sia in larghezza fissa e formati delimitati. Il sotto query FOR XML PATH mi dà il risultato che voglio, ma quando si tratta di qualcosa di diverso da piccole quantità di dati, può prendere un po '.

 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

Ho guardato perno ma la maggior parte degli esempi che ho trovato sono aggregazione delle informazioni. Voglio solo combinare le righe figlio e li virare sul genitore.

Vorrei anche sottolineare Non ho bisogno di trattare con i nomi delle colonne sia poiché l'uscita delle righe figlio o sarà una larghezza fissa stringa o una stringa delimitata.

Per esempio, date le seguenti tabelle:

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

per un ordine che ho bisogno di uscita:

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

o

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

I pensieri o suggerimenti? Sto usando SQL Server 2k5.

Impostazione Esempio:

   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)

utilizzando 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

che emette quello che voglio, ma è molto lento per grandi quantità di dati. Una delle tabelle figlio è oltre 2 milioni di righe, spingendo il tempo di elaborazione fuori a ~ 4 ore.

orderid     Products
----------- -----------------------
1             100  158  234
2             125
3             101  105  212  250
È stato utile?

Soluzione

Per definizione un perno sta per avere di aggregare in qualche modo, perché si può avere più righe con le stesse colonne chiave pivot. Se non si dispone di più righe, va bene -. Ma è ancora necessario scegliere un operatore di aggregazione (MIN, MAX, SUM)

Ma il costrutto FOR XML PATH è migliore per i più righe valori per singola stringa-colonna "pivot" operazione.

Non sono sicuro perché vostro è non un buon rendimento. Che indici avete sui tavoli? Che cosa significa il vostro look piano di esecuzione come?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top