2016-10-17 3 views
0

listagg работает, как ожидается, для poll_id=2.Как заполнить столбцы, а также строки?

Как я могу использовать то же самое для одной строки и нескольких столбцов?

with list_of_fruits as 
(select 1 as poll_id ,'Apple' as first_choice, 'Pear' as second_choice, 'Peach' as third_choice, 'Plum' as fourth_choice from dual union all 
select 2 as poll_id ,'Cherry' as first_choice, null as second_choice, null as third_choice, null as fourth_choice from dual union all 
select 2 as poll_id ,'Grape' as first_choice, null as second_choice, null as third_choice, null as fourth_choice from dual union all 
select 2 as poll_id ,'Kiwi' as first_choice, null as second_choice, null as third_choice, null as fourth_choice from dual union all 
select 3 as poll_id ,'Squash' as first_choice, 'Peas' as second_choice, '' as third_choice, null as fourth_choice from dual union all 
select 3 as poll_id ,null as first_choice, null as second_choice, null as third_choice, 'Barley' as fourth_choice from dual union all 
select 3 as poll_id ,null as first_choice, null as second_choice, 'Oats' as third_choice, null as fourth_choice from dual 

) select poll_id, listagg(first_choice,';') within group (order by poll_id) as sam 
    from list_of_fruits 
    group by poll_id 

Желаемая Выход

Consolodate все строки и столбцы (слева направо, сверху вниз), так что каждый poll_id имеет только одну строку в наборе результатов. Я хочу игнорировать нули.

1 Apple;Pear;Peach;Plum 
2 Cherry;Grape;Kiwi 
3 Squash;Peas;Barley;Oats 
+0

В вашем примере, для 'poll_id = 2', все три фрукты "'first_choice'". В каком порядке они должны появиться на выходе? (Имеет ли это значение? Например, они могут появляться в алфавитном порядке.) В противном случае, я предполагаю, что для любого заданного 'poll_id' значения, указанные в' first_choice', должны отображаться первыми, а затем в 'second_choice' и т. Д.? – mathguy

+0

Да, порядок имеет значение. Для каждого id, идите 1, 2, 3, 4-й выбор. Затем вторая строка, затем третья строка. и т. д. – zundarz

+0

@zundarz Я обновил свой ответ ниже. –

ответ

1
with 
    list_of_fruits 
      (poll_id, first_choice, second_choice, third_choice, fourth_choice) as (
     select 1,'Apple' , 'Pear', 'Peach', 'Plum' from dual union all 
     select 2,'Cherry', '' , ''  , ''  from dual union all 
     select 2,'Grape' , '' , 'Berry', ''  from dual union all 
     select 2,'Kiwi' , '' , ''  , ''  from dual union all 
     select 3,'Squash', 'Peas', ''  , ''  from dual union all 
     select 3,''  , '' , ''  , 'Barley' from dual union all 
     select 3,''  , '' , 'Oats' , ''  from dual 
    ), 
    prep (poll_id, first_choice, second_choice, third_choice, fourth_choice, rn) as (
     select poll_id, first_choice, second_choice, third_choice, fourth_choice, 
       row_number() over (partition by poll_id order by null) 
     from list_of_fruits 
    ) 
select poll_id, listagg(fruit, ',') within group (order by rn, choice) as sam 
from prep 
unpivot (fruit for choice in (first_choice as 1, second_choice as 2, 
              third_choice as 3, fourth_choice as 4)) 
group by poll_id 
order by poll_id -- ORDER BY is optional 
; 


    POLL_ID SAM 
---------- ------------------------------ 
     1 Apple,Pear,Peach,Plum 
     2 Grape,Berry,Cherry,Kiwi 
     3 Squash,Peas,Barley,Oats 
+1

Обратите внимание на 'order by null' в' row_number() 'в определении' rn' в 'prep'. Это означает, что строки для данного 'poll_id' будут в произвольном порядке, но они будут в ** некотором ** порядке. Если они должны быть в более конкретном порядке, это можно скорректировать в разделе 'order by' в' row_number'. Кроме того, я изменил CTE, чтобы иметь имена столбцов сразу после имени CTE. Это работает только в Oracle 11.2 и выше; для 11.1 вы можете перенести имена столбцов обратно в определение CTE (как было раньше), и сделать то же самое для 'prep'. – mathguy

+1

Я также добавил '' Berry'' как 'third_choice' в одну из строк для' poll_id = 2', чтобы проверить, правильно ли решение работает. – mathguy

Смежные вопросы