Ada beberapa cara untuk melakukan transformasi data ini. Anda memiliki akses ke PIVOT
fungsi maka itu akan menjadi yang termudah, tetapi jika tidak maka Anda dapat menggunakan fungsi agregat dan a CASE
.
Versi agregat / Kasus:
select personid,
max(case when optionid = 'A' then 1 else 0 end) OptionA,
max(case when optionid = 'B' then 1 else 0 end) OptionB,
max(case when optionid = 'C' then 1 else 0 end) OptionC
from PersonOptions
group by personid
order by personid;
Lihat SQL Fiddle dengan Demo
Pivot Statis:
select *
from
(
select personid, optionid
from PersonOptions
) src
pivot
(
count(optionid)
for optionid in ('A' as OptionA, 'B' OptionB, 'C' OptionC)
) piv
order by personid
Lihat SQL Fiddle dengan Demo
Versi Dinamis:
Dua versi di atas berfungsi dengan baik jika Anda memiliki jumlah nilai yang diketahui, tetapi jika nilai Anda tidak diketahui, maka Anda ingin mengimplementasikan sql dinamis dan di Oracle Anda dapat menggunakan prosedur:
CREATE OR REPLACE procedure dynamic_pivot_po(p_cursor in out sys_refcursor)
as
sql_query varchar2(1000) := 'select personid ';
begin
for x in (select distinct OptionID from PersonOptions order by 1)
loop
sql_query := sql_query ||
' , min(case when OptionID = '''||x.OptionID||''' then 1 else null end) as Option_'||x.OptionID;
dbms_output.put_line(sql_query);
end loop;
sql_query := sql_query || ' from PersonOptions group by personid order by personid';
dbms_output.put_line(sql_query);
open p_cursor for sql_query;
end;
/
Kemudian Anda mengembalikan hasilnya, Anda akan menggunakan:
variable x refcursor
exec dynamic_pivot_po(:x)
print x
Hasilnya sama dengan semua versi:
| PERSONID | OPTIONA | OPTIONB | OPTIONC |
------------------------------------------
| 1 | 1 | 1 | 0 |
| 2 | 0 | 0 | 1 |
| 3 | 0 | 1 | 0 |
| 4 | 1 | 0 | 1 |