2013-11-13 5 views
-1

Я пытаюсь создать инструкцию SQL для поворота переменной числа строк (до 5) в одну строку. Небольшая часть данных выглядит следующим образом:Как повернуть на несколько столбцов

+--------------+--------+-------+-------+ 
|  ID  | ItemID | Style | Qty | 
+--------------+--------+-------+-------+ 
| 00001-5A-2XL | F911-5 | F911 | 1.566 | 
| 00001-5A-2XL | 233-5 | 233 | 0.236 | 
| 00001-5A-3XL | F911-5 | F911 | 1.697 | 
| 00001-5A-3XL | 233-5 | 233 | 0.237 | 
| 00001-5A-4XL | F911-5 | F911 | 1.833 | 
| 00001-5A-4XL | 233-5 | 233 | 0.239 | 
| 00001-5A-L | F911-5 | F911 | 1.307 | 
| 00001-5A-L | 233-5 | 233 | 0.234 | 
+--------------+--------+-------+-------+ 

, и я хотел бы, чтобы повернуть данные, чтобы выглядеть следующим образом:

+--------------+------+--------+-----+--------+----+--------+----+--------+----+--------+ 
|  ID  | S1 | S1_Qty | S2 | S2_Qty | S3 | S3_Qty | S4 | S4_Qty | S5 | S5_Qty | 
+--------------+------+--------+-----+--------+----+--------+----+--------+----+--------+ 
| 00001-5A-2XL | F911 | 1.566 | 233 | 0.236 | |  | |  | |  | 
| 00001-5A-3XL | F911 | 1.566 | 233 | 0.237 | |  | |  | |  | 
| 00001-5A-4XL | F911 | 1.566 | 233 | 0.239 | |  | |  | |  | 
| 00001-5A-L | F911 | 1.566 | 233 | 0.234 | |  | |  | |  | 
+--------------+------+--------+-----+--------+----+--------+----+--------+----+--------+ 

Я немного потерял, когда дело доходит до поворота, в частности, когда я хочу поворачивать как Style, так и Quantity в мои столбцы. Там мне может быть до 5 стилей (строк), которые нужно перевести в до 5 столбцов.

Любые предложения, указатели и т. Д. Были бы очень признательны.

+0

Является ли такой же стиль в той же колонке обязательным? –

+0

Нет, на самом деле, это нежелательно, так как я хотел бы наивысшее количество в первом столбце, затем следующее наибольшее количество во втором и т. Д. ... вплоть до самого низкого количества, до 5 пар стиля/количества. –

ответ

6

Существует несколько различных способов получения результата в зависимости от ваших потребностей.

Не совсем понятно, если вам нужно использовать два разных агрегата для получения результата. Если вам нужно, возможно sum(qty), а затем использовать max() на style, я предложил бы использовать агрегатную функцию с выражением CASE, чтобы получить результат:

select id, 
    max(case when ItemID = 'F911-5' then Style end) Style1, 
    sum(case when ItemID = 'F911-5' then Qty else 0 end) Qty1, 
    max(case when ItemID = '233-5' then Style end) Style2, 
    sum(case when ItemID = '233-5' then Qty else 0 end) Qty2 
from yourtable 
group by id; 

См SQL Fiddle with Demo. Затем, когда у вас есть новые значения ItemId, вы просто добавите новые столбцы.

Вы также можете использовать функцию PIVOT, но так как вам нужно PIVOT на двух столбцах, я бы сначала не открыл столбцы style и Qty. Это будет конвертировать несколько столбцов данных в несколько строк, и вы можете получить результат с помощью функции UNPIVOT или CROSS ОТНОСИТЬСЯ - базовый синтаксис будет:

select id, 
    col = col+cast(seq as varchar(10)), value 
from 
(
    select id, itemid, style, qty, 
    row_number() over(partition by id 
         order by qty desc) seq 
    from yourtable 
) src 
cross apply 
(
    select 'style', style union all 
    select 'qty', cast(qty as varchar(10)) 
) c(col, value) 

См SQL Fiddle with Demo. Это превращает данные в несколько строк, которые затем могут быть поворотными:

|   ID | COL | VALUE | 
|--------------|--------|---------| 
| 00001-5A-2XL | style1 | F911 | 
| 00001-5A-2XL | qty1 | 1.56600 | 
| 00001-5A-2XL | style2 |  233 | 
| 00001-5A-2XL | qty2 | 0.23600 | 
| 00001-5A-3XL | style1 | F911 | 

Затем вы можете применить функцию PIVOT, чтобы получить конечный результат:

select id, style1, qty1, style2, qty2 
from 
(
    select id, 
    col = col+cast(seq as varchar(10)), value 
    from 
    (
    select id, itemid, style, qty, 
     row_number() over(partition by id 
         order by qty desc) seq 
    from yourtable 
) src 
    cross apply 
    (
    select 'style', style union all 
    select 'qty', cast(qty as varchar(10)) 
) c(col, value) 
) d 
pivot 
(
    max(value) 
    for col in (style1, qty1, style2, qty2) 
) piv; 

SQL Fiddle with Demo См. Наконец, если у вас есть неизвестное число значений, то вы можете использовать динамический SQL, чтобы получить результат:

DECLARE @cols AS NVARCHAR(MAX), 
    @query AS NVARCHAR(MAX) 

select @cols = STUFF((SELECT ',' + QUOTENAME(col+cast(seq as varchar(10))) 
        from 
        (
         select row_number() over(partition by id 
               order by qty desc) seq 
         from yourtable 
        ) t 
        cross apply 
        (
         select 'style', 1 union all 
         select 'qty', 2 
        ) c (col, so) 
        group by col, so, seq 
        order by seq, so 
      FOR XML PATH(''), TYPE 
      ).value('.', 'NVARCHAR(MAX)') 
     ,1,1,'') 

set @query = 'SELECT id, ' + @cols + ' 
      from 
      (
       select id, 
        col = col+cast(seq as varchar(10)), value 
       from 
       (
        select id, itemid, style, qty, 
        row_number() over(partition by id 
             order by qty desc) seq 
        from yourtable 
       ) src 
       cross apply 
       (
        select ''style'', style union all 
        select ''qty'', cast(qty as varchar(10)) 
       ) c(col, value) 
      ) x 
      pivot 
      (
       max(value) 
       for col in (' + @cols + ') 
      ) p ' 

execute sp_executesql @query; 

SQL Fiddle with Demo См. Они дают результаты:

|   ID | STYLE1 | QTY1 | STYLE2 | QTY2 | 
|--------------|--------|---------|--------|---------| 
| 00001-5A-2XL | F911 | 1.56600 | 233 | 0.23600 | 
| 00001-5A-3XL | F911 | 1.69700 | 233 | 0.23700 | 
| 00001-5A-4XL | F911 | 1.83300 | 233 | 0.23900 | 
| 00001-5A-L | F911 | 1.30700 | 233 | 0.23400 | 
Смежные вопросы