2014-01-20 3 views
1

У меня есть данные, как это:ОСИ на несколько колонок

Product Group  Product Level Quatity Sold  Trend 
============================================================== 
Group 1   L1    10    up 
Group 1   L2    20    up 
Group 1   L3    30    down 
Group 2   L1    20    up 
Group 2   L2    40    up 
Group 2   L3    60    down 
Group 2   L4    80    down 

Мне нужно, чтобы получить данные в этом формате:

Product Group  L1  L1Trend L2 L2Trend L3 L3Trend L4  L4Trend 
====================================================================================== 
Group 1   10  up   20 up   30 down 
Group 2   20  up   40 up   60 down  80  down 

Я был в состоянии повернуть на «уровень продукта», используя что-то например:

PIVOT (MAX(quatity)  FOR productlevel IN([L1],[L2],[L3],[L4]) AS p 

но потерялся при работе с трендом.

Спасибо.

ответ

3

Вы можете получить желаемый результат за счет реализации функции PIVOT, но я бы первый UNPIVOT ваши несколько столбцов из Quantity Sold и Trend. Процесс univot будет преобразовывать их из нескольких столбцов в несколько строк данных.

Поскольку вы используете SQL Server 2008+, вы можете использовать CROSS APPLY с VALUES для UNPIVOT данные:

select [Product Group], 
    col, value 
from yourtable 
cross apply 
(
    values 
    ([Product Level], cast([Quatity Sold] as varchar(10))), 
    ([Product Level]+'trend', [trend]) 
) c (col, value); 

См SQL Fiddle with Demo Это преобразует данные таблицы в формате:

| PRODUCT GROUP |  COL | VALUE | 
|---------------|---------|-------| 
|  Group 1 |  L1 | 10 | 
|  Group 1 | L1trend | up | 
|  Group 1 |  L2 | 20 | 
|  Group 1 | L2trend | up | 
|  Group 1 |  L3 | 30 | 
|  Group 1 | L3trend | down | 

сейчас вы можете легко применить функцию PIVOT:

select [Product Group], 
    L1, L1trend, 
    L2, L2trend, 
    L3, L3trend, 
    L4, L4trend 
from 
(
    select [Product Group], 
    col, value 
    from yourtable 
    cross apply 
    (
    values 
     ([Product Level], cast([Quatity Sold] as varchar(10))), 
     ([Product Level]+'trend', [trend]) 
) c (col, value) 
) d 
pivot 
(
    max(value) 
    for col in (L1, L1trend, L2, L2trend, 
       L3, L3trend, L4, L4trend) 
) piv; 

См. SQL Fiddle with Demo. Это дает вам окончательный результат:

| PRODUCT GROUP | L1 | L1TREND | L2 | L2TREND | L3 | L3TREND |  L4 | L4TREND | 
|---------------|----|---------|----|---------|----|---------|--------|---------| 
|  Group 1 | 10 |  up | 20 |  up | 30 | down | (null) | (null) | 
|  Group 2 | 20 |  up | 40 |  up | 60 | down |  80 | down | 
0

Вы можете потенциально сделать это с помощью связанных подзапросов:

select productGroup as [Product Group] 
    , (select sum(quantitySold) from myTable where productGroup = a.productGroup and productLevel = 'L1') as L1 
    , (select max(trend) from myTable where productGroup = a.productGroup and productLevel = 'L1') as L1Trend 
    , (select sum(quantitySold) from myTable where productGroup = a.productGroup and productLevel = 'L2') as L2 
    , (select max(trend) from myTable where productGroup = a.productGroup and productLevel = 'L2') as L2Trend 
    -- etc. 
from myTable a 
group by productGroup 
order by productGroup 

Вот example SqlFiddle.

Это может помочь вам увидеть это, прежде чем использовать ключевое слово PIVOT.

Если вы не знаете, сколько у вас значений productLevel, вам потребуется динамическое решение.

+0

благодарит за ответ. Есть ли способ использовать PIVOT для решения этой проблемы без использования коррелированных подзапросов? – notlkk

0

, если вы предпочитаете использовать стержень, вы можете попробовать это:

select productgroup, 
coalesce(L1up,L1down,'') L1, case when L1up is not null then 'up' when L1down is not null then 'down' else '' end L1trend, 
coalesce(L2up,L2down,'') L2, case when L2up is not null then 'up' when L2down is not null then 'down' else '' end L2trend, 
coalesce(L3up,L3down,'') L3, case when L3up is not null then 'up' when L3down is not null then 'down' else '' end L3trend, 
coalesce(L4up,L4down,'') L4, case when L4up is not null then 'up' when L4down is not null then 'down' else '' end L4trend 
from 
(
select productgroup, [L1up],[L2up],[L3up],[L4up],[L1down],[L2down],[L3down],[L4down] 
from (select productgroup, productlevel+trend pt, quantity from mytable) t 
PIVOT (MAX(quantity) 
FOR pt IN([L1up],[L2up],[L3up],[L4up],[L1down],[L2down],[L3down],[L4down])) as p 
) t 
Смежные вопросы