Potřebujete funkci PIVOT s definicí dynamických sloupců. Nejjednodušší způsob je pivot xml:
create table tst_data (id int primary key, source varchar2(255));
insert into tst_data values (1, 'INTERNET');
insert into tst_data values (2, 'DEMO');
insert into tst_data values (3, 'INTERNET');
insert into tst_data values (4, 'SALES');
insert into tst_data values (5, 'INTERNET');
insert into tst_data values (6, 'DEMO');
insert into tst_data values (7, 'INTERNET');
insert into tst_data values (8, 'COM');
commit;
select * from (
select source from tst_data
)
pivot xml
(
count(1)
for source in (select distinct t.source from tst_data t)
)
Poté, co potřebujete zpracovat data XML:
<PivotSet>
<item>
<column name = "SOURCE">COM</column>
<column name = "COUNT(1)">1</column>
</item>
<item>
<column name = "SOURCE">DEMO</column>
<column name = "COUNT(1)">2</column>
</item>
<item>
<column name = "SOURCE">INTERNET</column>
<column name = "COUNT(1)">4</column>
</item>
<item>
<column name = "SOURCE">SALES</column>
<column name = "COUNT(1)">1</column>
</item>
</PivotSet>
PIVOT XML
podporuje definici dynamických sloupců (for source in (select distinct t.source from tst_data t)
), ale vrací data XML. Extractvalue
a xmltable
funkce umožňují dotazovat se na konkrétní sloupce z XML na straně serveru, ale názvy polí musíte zadat předem. Předpokládám tedy, že jej analyzuji na straně klienta.
Pokud chcete dělat vše na vrstvě DB, existuje jiný přístup. PIVOT
(nikoli XML) vyžaduje názvy sloupců for source in ('INTERNET', 'DEMO', 'COM', ...)
. Je možné vygenerovat takový dotaz a vrátit kurzor na stranu klienta:
CREATE OR REPLACE FUNCTION FUNCTION1 RETURN SYS_REFCURSOR AS
cur sys_refcursor;
BEGIN
open cur for 'select * from dual'; // generate PIVOT query here
RETURN cur;
END FUNCTION1;
Neznám žádnou metodu, jak vytvořit jednoduchý netypizovaný dotaz z kurzoru (na straně serveru), takže pokud chcete použít prostý SQL dotaz, udělejte to ve dvou krocích:
- Vygenerujte PIVOT dotaz s pojmenovanými sloupci ve funkci PL/SQL;
- Spusťte dotaz ze svého klienta.