Usar sql dinâmico para um resultado em que as colunas são desconhecidas no momento da execução é um pouco trabalhoso no Oracle em comparação com alguns outros RDMBS.
Como o tipo de registro para a saída ainda é desconhecido, ele não pode ser definido antecipadamente.
No Oracle 11g, uma maneira é usar um procedimento sem nome que gera uma tabela temporária com o resultado dinâmico.
Em seguida, selecione os resultados dessa tabela temporária.
declare
v_sqlqry clob;
v_cols clob;
begin
-- Generating a string with a list of the unique names
select listagg(''''||CCL||''' as "'||CCL||'"', ', ') within group (order by CCL)
into v_cols
from
(
select distinct CCL
from tableA
);
-- drop the temporary table if it exists
EXECUTE IMMEDIATE 'DROP TABLE tmpPivotTableA';
EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF;
-- A dynamic SQL to create a temporary table
-- based on the results of the pivot
v_sqlqry := '
CREATE GLOBAL TEMPORARY TABLE tmpPivotTableA
ON COMMIT PRESERVE ROWS AS
SELECT *
FROM (SELECT ID, CCL, Flag FROM TableA) src
PIVOT (MAX(Flag) FOR (CCL) IN ('||v_cols||')) pvt';
-- dbms_output.Put_line(v_sqlqry); -- just to check how the sql looks like
execute immediate v_sqlqry;
end;
/
select * from tmpPivotTableA;
Devoluções:
ID adam john rob terry
-- ---- ---- --- -----
1 x x x
2 x
Você pode encontrar um teste em db<>fiddle aqui
No Oracle 11g, outro truque legal (criado por Anton Scheffer) para ser usado pode ser encontrado neste blog. Mas você terá que adicionar a função pivot para isso.
O código fonte pode ser encontrado neste zip
Depois disso, o SQL pode ser tão simples quanto isto:
select * from
table(pivot('SELECT ID, CCL, Flag FROM TableA'));
Você encontrará um teste no db<>fiddle aqui