Bạn cần một hàm PIVOT với định nghĩa cột động. Cách đơn giản nhất là xoay 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)
)
Sau khi bạn cần xử lý dữ liệu 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
hỗ trợ định nghĩa cột động (for source in (select distinct t.source from tst_data t)
) tuy nhiên nó trả về dữ liệu XML. Extractvalue
và xmltable
các hàm cho phép truy vấn các cột cụ thể từ XML ở phía máy chủ nhưng bạn phải chỉ định trước tên trường. Vì vậy, tôi giả định phân tích cú pháp nó ở phía máy khách.
Nếu bạn muốn làm mọi thứ trên DB-layer, có một cách tiếp cận khác. PIVOT
(không phải XML) yêu cầu tên cột for source in ('INTERNET', 'DEMO', 'COM', ...)
. Có thể tạo một truy vấn như vậy và trả về một con trỏ về phía khách hàng:
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;
Tôi không biết bất kỳ phương pháp nào để tạo một truy vấn không định kiểu đơn giản từ con trỏ (ở phía máy chủ), vì vậy nếu bạn muốn sử dụng một truy vấn SQL thuần túy, hãy thực hiện theo hai bước:
- Tạo truy vấn PIVOT với các cột được đặt tên trong hàm PL / SQL;
- Chạy truy vấn từ khách hàng của bạn.