In Oracle 11, you can use the pivot
clause with the unpivot
:
with count_table as ( select 1001 device_id, 4 quantity from dual union all select 1002 device_id, 20 quantity from dual union all select 1003 device_id, 1 quantity from dual ), device_table as ( select 1001 id, 'Yes' wifi, 'No' email, 'No' bluetooth from dual union all select 1002 id, 'Yes' wifi, 'Yes' email, 'No' bluetooth from dual union all select 1003 id, 'Unknown' wifi, 'Unknown' email, 'Yes' bluetooth from dual ) ---------------------------------------- select * from ( select feature, yes_no_unknown, sum(quantity) quantity from count_table c join device_table d on c.device_id = d.id unpivot ( yes_no_unknown for feature in (wifi, email, bluetooth) ) group by feature, yes_no_unknown ) pivot ( sum (quantity) for yes_no_unknown in ('Yes' as yes, 'No' as no, 'Unknown' as unknown) ) ;
Alternatively, you can join two existing tables to a third table containing values ββfor the three desired rows. This is probably a little easier to read:
with count_table as ( select 1001 device_id, 4 quantity from dual union all select 1002 device_id, 20 quantity from dual union all select 1003 device_id, 1 quantity from dual ), device_table as ( select 1001 id, 'Yes' wifi, 'No' email, 'No' bluetooth from dual union all select 1002 id, 'Yes' wifi, 'Yes' email, 'No' bluetooth from dual union all select 1003 id, 'Unknown' wifi, 'Unknown' email, 'Yes' bluetooth from dual ) ---------------------------------------- select f.txt, sum(case when ( f.txt = 'wifi' and d.wifi = 'Yes' ) or ( f.txt = 'email' and d.email = 'Yes' ) or ( f.txt = 'bluetooth' and d.bluetooth = 'Yes' ) then c.quantity else 0 end ) yes, sum(case when ( f.txt = 'wifi' and d.wifi = 'No' ) or ( f.txt = 'email' and d.email = 'No' ) or ( f.txt = 'bluetooth' and d.bluetooth = 'No' ) then c.quantity else 0 end ) no, sum(case when ( f.txt = 'wifi' and d.wifi = 'Unknown' ) or ( f.txt = 'email' and d.email = 'Unknown' ) or ( f.txt = 'bluetooth' and d.bluetooth = 'Unknown' ) then c.quantity else 0 end ) unknown from count_table c join device_table d on c.device_id = d.id cross join ( select 'wifi' txt from dual union all select 'email' txt from dual union all select 'bluetooth' txt from dual ) f group by f.txt;