Есть несколько способов, которыми вы можете выполнить это преобразование данных. У вас есть доступ к PIVOT
функции, тогда это будет проще всего, но если нет, то вы можете использовать агрегатную функцию и a CASE
.
Версия агрегата / дела:
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;
Смотрите SQL Fiddle с демо
Статический Пивот:
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
Смотрите SQL Fiddle с демо
Динамическая версия:
Две вышеупомянутые версии прекрасно работают, если у вас есть известное количество значений, но если ваши значения неизвестны, тогда вы захотите реализовать динамический sql, а в Oracle вы можете использовать процедуру:
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;
/
Затем вы вернете результаты, вы будете использовать:
variable x refcursor
exec dynamic_pivot_po(:x)
print x
Результаты одинаковы для всех версий:
| PERSONID | OPTIONA | OPTIONB | OPTIONC |
------------------------------------------
| 1 | 1 | 1 | 0 |
| 2 | 0 | 0 | 1 |
| 3 | 0 | 1 | 0 |
| 4 | 1 | 0 | 1 |
where a.personId = a2.personId order by a2.personId for xml path('')
. a2 - таблица в подзапросе. Затем я разделяю данные в Excel, используя текст в столбцы с запятой в качестве разделителя. Я надеялся найти способ сделать это в обычном SQL без необходимости писать процедуру, но, возможно, нет никакого способа. Должен бежать в данный момент, но я постараюсь опубликовать пример этого, чтобы лучше объяснить.Это было бы эквивалентно в синтаксисе SQL Server. Судя по моему прочтению документации Oracle, NULLIF и PIVOT имеют тот же формат, что и их род SQL Server. Задачей будет сводный список, который должен быть статическим, если вы не сделаете запрос динамическим, как показывает Ицик, но я понятия не имею, можно ли его перевести на P / SQL
источник
Я предпочитаю сводить запрос вручную, но вы также можете использовать
PIVOT
.источник
PIVOT
синтаксис более запутанный по сравнению с подходом, который я использую. Однако я знаю, что оба они дают один и тот же результат, и я согласен, что другие люди могут думать иначе.