Sử dụng sql động cho kết quả trong đó các cột không xác định tại thời điểm thực thi là một chút rắc rối trong Oracle so với một số RDMBS khác.
Vì loại bản ghi cho đầu ra vẫn chưa được biết nên không thể xác định trước nó.
Trong Oracle 11g, một cách là sử dụng thủ tục không tên để tạo bảng tạm thời với kết quả xoay vòng.
Sau đó, chọn kết quả từ bảng tạm thời đó.
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;
Trả về:
ID adam john rob terry
-- ---- ---- --- -----
1 x x x
2 x
Bạn có thể tìm thấy bài kiểm tra trên db <> fiddle tại đây
Trong Oracle 11g, bạn có thể tìm thấy một thủ thuật thú vị khác (do Anton Scheffer tạo ra) được sử dụng trong blog này. Nhưng bạn sẽ phải thêm hàm pivot cho nó.
Bạn có thể tìm thấy mã nguồn trong zip này
Sau đó, SQL có thể đơn giản như sau:
select * from
table(pivot('SELECT ID, CCL, Flag FROM TableA'));
Bạn sẽ tìm thấy bài kiểm tra trên db <> fiddle tại đây