T-SQL Самый эффективный ряд к столбцу? CrosStab для XML Path, Pivot

StackOverflow https://stackoverflow.com/questions/2622826

Вопрос

Я ищу самый исполнительный способ повернуть ряды в колонны. У меня есть требование выводить содержимое БД (не фактическую схему ниже, но концепция похожа) как в фиксированной ширине, так и в форматах с разделителями. Ниже приведен к запросу 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

Я посмотрел на пивот, но большинство примеров, которые я нашел, - это агрегационная информация. Я просто хочу объединить дочерние ряды и прикрепить их на родитель.

Я также должен указать, что мне не нужно иметь дело с именами столбцов, поскольку вывод дочерних строк будет либо строкой фиксированной шириной или разделите строку.

Например, учитывая следующие таблицы:

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 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

который выводит то, что я хочу, однако очень медленно для больших объемов данных. Один из детских столов составляет более 2 миллионов строк, нажав время обработки до ~ 4 часа.

orderid     Products
----------- -----------------------
1             100  158  234
2             125
3             101  105  212  250
Это было полезно?

Решение

По определению, поворот должен быть вообще связан, потому что вы можете иметь несколько строк с одинаковыми столбцами ключей поворота. Если у вас нет нескольких строк, это нормально - но вам все равно нужно выбрать агрегатный оператор (мин, максимум, сумму).

Но FOR XML PATH Конструкция лучше для нескольких строк-значений к однотруконному колонку «Pivot».

Я не уверен, почему твой не выступает хорошо. Какие указатели у вас есть на столах? Как выглядит ваш план исполнения?

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top