Att använda dynamisk sql för ett resultat där kolumnerna är okända vid tidpunkten för exekvering är lite av ett krångel i Oracle jämfört med vissa andra RDMBS.
Eftersom posttypen för utdata ännu är okänd, kan den inte definieras i förväg.
I Oracle 11g är ett sätt att använda en namnlös procedur som genererar en temporär tabell med det pivoterade resultatet.
Välj sedan resultaten från den tillfälliga tabellen.
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;
Returer:
ID adam john rob terry
-- ---- ---- --- -----
1 x x x
2 x
Du kan hitta ett test på db<>fiol här
I Oracle 11g finns ett annat coolt trick (skapat av Anton Scheffer) som ska användas i den här bloggen. Men du måste lägga till pivotfunktionen för det.
Källkoden finns i denna zip
Efter det kan SQL vara så enkelt som det här:
select * from
table(pivot('SELECT ID, CCL, Flag FROM TableA'));
Du hittar ett test på db<>fiol här