Vous pouvez effectuer cette transformation de données de plusieurs manières. Vous avez accès à la PIVOT
fonction, ce sera la plus simple, mais sinon, vous pouvez utiliser une fonction d'agrégation et a CASE
.
Version agrégée / cas:
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;
Voir SQL Fiddle avec démo
Pivot statique:
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
Voir SQL Fiddle avec démo
Version dynamique:
Les deux versions ci-dessus fonctionnent très bien si vous avez un nombre connu de valeurs, mais si vos valeurs sont inconnues, alors vous voudrez implémenter SQL dynamique et dans Oracle, vous pouvez utiliser une procédure:
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;
/
Ensuite, vous retournez les résultats, vous utiliserez:
variable x refcursor
exec dynamic_pivot_po(:x)
print x
Les résultats sont les mêmes avec toutes les versions:
| PERSONID | OPTIONA | OPTIONB | OPTIONC |
------------------------------------------
| 1 | 1 | 1 | 0 |
| 2 | 0 | 0 | 1 |
| 3 | 0 | 1 | 0 |
| 4 | 1 | 0 | 1 |