Reputation: 148
I need to get a query result like this:
|Person1 |Person2 |Person3 |...
------------------------------------------------------------------------------------
Date1 |function(Person1Id,Date1)|function(Person2Id,Date1)|function(Person3Id,Date1)|...
Date2 |function(Person1Id,Date2)|function(Person2Id,Date2)|function(Person3Id,Date2)|...
Date3 |function(Person1Id,Date3)|function(Person2Id,Date3)|function(Person3Id,Date3)|...
.
.
.
Dates are coming from the user and PersonIds are coming from a table. What I need to is just sending ids and dates o the function and get the result of it. Since I am working on oracle v10.2.0 pivoting does not work and writing case...when statements for each person will not work because there are lots of people in the table I am fetching.
Any help appreciated.
Upvotes: 0
Views: 46
Reputation: 65363
You can use Conditional Aggregation within DB version 10g
such as
SELECT myDate,
MAX(CASE WHEN PersonId=1 THEN myfunc(PersonId,myDate) END) AS Person1,
MAX(CASE WHEN PersonId=2 THEN myfunc(PersonId,myDate) END) AS Person2,
MAX(CASE WHEN PersonId=3 THEN myfunc(PersonId,myDate) END) AS Person3
FROM t
GROUP BY myDate
Update : Yet, there exists an option, even in DB 10g
for dynamic pivoting by using SYS_REFCURSOR
, eg. using PL/SQL rather than using SQL only, and show the result set on the command line if you're using SQL Developer. Create a stored function
CREATE OR REPLACE FUNCTION get_person_rs RETURN SYS_REFCURSOR IS
v_recordset SYS_REFCURSOR;
v_sql VARCHAR2(32767);
v_str VARCHAR2(32767);
BEGIN
WITH tt AS
(
SELECT PersonId,
ROW_NUMBER() OVER (ORDER BY PersonId) AS rn
FROM t
GROUP BY PersonId
)
SELECT TO_CHAR(RTRIM(XMLAGG(XMLELEMENT(e,
'MAX(CASE WHEN PersonId = '||PersonId||
' THEN myfunc(PersonId,myDate)
END) AS Person'||rn
, ',')).EXTRACT('//text()').GETCLOBVAL(), ','))
INTO v_str
FROM tt;
v_sql :=
'SELECT myDate, '|| v_str ||'
FROM t
GROUP BY myDate';
OPEN v_recordset FOR v_sql;
RETURN v_recordset;
END;
in which, ROW_NUMBER()
Analytic function, which is available in 10g
, is used, but LISTAGG()
string aggregation function is not yet in 10g
. So XMLAGG
is used instead. This generated SQL string within the function is also exactly same as the above one, eg. in Conditionally Aggregated Logic.
Then run the below code :
VAR rc REFCURSOR
EXEC :rc := get_person_rs;
PRINT rc
from SQL Developer's Command Line in order to see the expected result set dynamically generated by currently existing data.
Upvotes: 1