Question

Je cherche le moyen le plus performant pour transformer les lignes en colonnes. J'ai une obligation de sortir le contenu de la DB (schéma ci-dessous non réel, mais le concept est similaire) en largeur fixe et formats délimités. La requête ci-dessous pour PATH XML me donne le résultat que je veux, mais quand traiter autre chose que de petites quantités de données, peut prendre un certain temps.

 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

J'ai regardé pivot mais la plupart des exemples que j'ai trouvé regroupent des informations. Je veux juste combiner les lignes enfants et les virer de bord sur le parent.

Je tiens également à souligner que je ne ai pas besoin de traiter les noms de colonnes, soit depuis la sortie des lignes enfants seront soit une largeur fixe corde ou une chaîne Délimité.

Par exemple, étant donné les tableaux suivants:

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

pour un ordre que je dois sortie:

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

ou

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

Pensées ou suggestions? J'utilise SQL Server 2k5.

Exemple de configuration:

   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)

à l'aide du PATH 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

qui délivre ce que je veux, est cependant très lent pour de grandes quantités de données. L'une des tables de l'enfant est plus de 2 millions de lignes, poussant le temps de traitement vers ~ 4 heures.

orderid     Products
----------- -----------------------
1             100  158  234
2             125
3             101  105  212  250
Était-ce utile?

La solution

Par définition, un PIVOT va devoir rassembler en quelque sorte, parce que vous pouvez avoir plusieurs lignes avec les mêmes colonnes de clés de pivot. Si vous n'avez pas plusieurs lignes, c'est très bien -. Mais vous devez toujours choisir un opérateur global (MIN, MAX, SUM)

Mais la construction de FOR XML PATH est meilleur pour les lignes multiples valeurs à une seule chaîne colonne opération « pivot ».

Je ne sais pas pourquoi le vôtre ne fonctionne pas bien. Quels index avez-vous sur les tables? Qu'est-ce que votre look plan d'exécution comme?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top