Reputation: 275
I want to write a procedure using collections.
I have a table - employee
- and I want to return the following:
My final recordset or array table should return below values. TEST1, TEST2, TEST3, TEST4 are description values residing in DESCRIPTION TABLE where as count values are from employee table.
Description COUNT
TEST1 10
TEST2 15
TEST3 25
TEST4 50
Please help with implementation.
Upvotes: 3
Views: 917
Reputation: 220842
This solution won't use your DESCRIPTION
table to calculate counts dynamically, as that would be rather hard to achieve. So, here's a solution with hard-coded TESTn
descriptions.
First, create the record type:
CREATE TYPE count_t AS OBJECT (
description varchar2(100),
cnt NUMBER(10)
);
Then, create the table type:
CREATE TYPE count_tt AS TABLE OF count_t;
Now, write the function:
CREATE OR REPLACE FUNCTION counts RETURN count_tt
IS
v_result count_tt;
BEGIN
SELECT count_t(description, cnt)
BULK COLLECT INTO v_result
FROM (
SELECT
count(CASE WHEN sal < 10000 THEN 1 END) TEST1,
count(CASE WHEN dept > 10 THEN 1 END) TEST2,
count(CASE WHEN hiredate > SYSDATE - 60 THEN 1 END) TEST3,
count(CASE WHEN grade = 1 THEN 1 END) TEST4
FROM employees
) t
-- Behold, the power of unpivot!
UNPIVOT (
cnt FOR description IN ("TEST1", "TEST2", "TEST3", "TEST4")
);
RETURN v_result;
END counts;
/
Now, call the function, e.g. from SQL:
SELECT * FROM TABLE(counts)
Enjoy.
By the way, I've written up a blog post comparing this solution from a performance perspective with others that do not use UNPIVOT
Upvotes: 3