Could you use the PIPELINED function to achieve your goal?
I wrote an example of such a function. The example is based on a table, sample data, and a PIVOT query from Tom Kyte articles that you can find on his website:
Tom Keith article on PIVOT / UNPIVOT
Tom Keith article on PIPELINED features
An example works as follows.
We create two types:
- t_pivot_test_obj - the type that contains the columns that we want to extract from XML
- t_pivot_test_obj_tab - type of nested table of specified objects.
Then we create a PIPELINED function that contains a query with PIVOT that generates XML (so you donβt need to hardcode the values ββyou want to flip). This function extracts data from the generated XML and passes the string (PIPE) to the calling request as it is created (on the fly - it is not generated immediately, which is important for performance).
Finally, you write a query that selects records from this function (at the end this is an example of such a query).
CREATE TABLE pivot_test ( id NUMBER, customer_id NUMBER, product_code VARCHAR2(5), quantity NUMBER ); INSERT INTO pivot_test VALUES (1, 1, 'A', 10); INSERT INTO pivot_test VALUES (2, 1, 'B', 20); INSERT INTO pivot_test VALUES (3, 1, 'C', 30); INSERT INTO pivot_test VALUES (4, 2, 'A', 40); INSERT INTO pivot_test VALUES (5, 2, 'C', 50); INSERT INTO pivot_test VALUES (6, 3, 'A', 60); INSERT INTO pivot_test VALUES (7, 3, 'B', 70); INSERT INTO pivot_test VALUES (8, 3, 'C', 80); INSERT INTO pivot_test VALUES (9, 3, 'D', 90); INSERT INTO pivot_test VALUES (10, 4, 'A', 100); COMMIT; CREATE TYPE t_pivot_test_obj AS OBJECT ( customer_id NUMBER, product_code VARCHAR2(5), sum_quantity NUMBER ); / CREATE TYPE t_pivot_test_obj_tab IS TABLE OF t_pivot_test_obj; / CREATE OR REPLACE FUNCTION extract_from_xml RETURN t_pivot_test_obj_tab PIPELINED AS v_xml XMLTYPE; v_item_xml XMLTYPE; v_index NUMBER; v_sum_quantity NUMBER; CURSOR c_customer_items IS SELECT customer_id, product_code_xml FROM (SELECT customer_id, product_code, quantity FROM pivot_test) PIVOT XML (SUM(quantity) AS sum_quantity FOR (product_code) IN (SELECT DISTINCT product_code FROM pivot_test)); BEGIN
Output:
CUSTOMER_ID PRODUCT_CODE SUM_QUANTITY