2016-10-17 5 views
0

listaggは、poll_id=2の期待どおりに機能します。列と行を集計する方法は?

1行と複数列で同じように使用できますか?

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が結果セット内の唯一の行を有するように(右、上から下へ左)は、すべての行と列。私はnullを無視したい。あなたの例では

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

、 'poll_id = 2 'のために、すべての3つの果実は "'first_choice'" です。出力にどのような順序で表示する必要がありますか?そうでなければ、与えられた 'poll_id'に対して、' first_choice'で与えられた果実が最初に現れ、次に 'second_choice'などで果実が現れると仮定します。 – mathguy

+0

はい注文は問題ありません。それぞれのIDに対して、1位、2位、3位、4位に進みます。その後、2行目、3行目。 – 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

'prep'の' rn'の定義で 'row_number()'に 'order by null'があることに注目してください。つまり、指定された 'poll_id'の行は任意の順序になりますが、** some **の順序になります。それらがより特定の順序でなければならない場合、 'row_number'の' order by'節でそれを調整することができます。また、CTEの名前の直後に列名を持つようにCTEを変更しました。これはOracle 11.2以降でのみ動作します。 11.1では、CTE定義内に列名を戻すことができます(最初は同じように)。 – mathguy

+1

解決策が正しく動作するかどうかをテストする 'poll_id = 2'の行の' third_choice'に '' Berry''を追加しました。 – mathguy

関連する問題