Použití dynamického SQL pro výsledek, kde jsou sloupce v době provádění neznámé, je v Oracle ve srovnání s některými jinými RDMBS trochu problém.
Protože typ záznamu pro výstup je dosud neznámý, nelze jej předem definovat.
V Oracle 11g je jedním ze způsobů použití bezejmenné procedury, která generuje dočasnou tabulku s pivotovaným výsledkem.
Potom vyberte výsledky z této dočasné tabulky.
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;
Vrácení:
ID adam john rob terry
-- ---- ---- --- -----
1 x x x
2 x
Test na db<>fiddle najdete zde
V Oracle 11g lze v tomto blogu nalézt další skvělý trik (vytvořil Anton Scheffer), který lze použít. K tomu ale budete muset přidat funkci pivot.
Zdrojový kód najdete v tomto zipu
Poté může být SQL takto jednoduchý:
select * from
table(pivot('SELECT ID, CCL, Flag FROM TableA'));
Test na db<>fiddle najdete zde