I believe what you are looking for is the "grouping" function. It will set a 0/1 flag to allow you to detect when a row is the result of a ROLLUP or CUBE operation. You would have to add a column or 2 (or more) to your query to retrieve these values for inspection by the client application. Here is an example I set up and then in anticipation of your next question (hey -- why doesn't rollup work in PLSQL), I'll offer up how to let rollup work in plsql (see
</code>
http://asktom.oracle.com/pls/asktom/f?p=100:11:::::P11_QUESTION_ID:186812348071 <code>for why it doesn't work)
ask_tom@OSI1.WORLD> variable P_SAL number
ask_tom@OSI1.WORLD> exec :P_SAL := 1000
PL/SQL procedure successfully completed.
ask_tom@OSI1.WORLD> select deptno, job, sum(sal),
2 decode(grouping(job),1,1,NULL) job_rollup,
3 decode(grouping(deptno),1,1,NULL) deptno_rollup
4 from emp
5 where sal > :P_SAL
6 group by rollup(deptno,job)
7 /
DEPTNO JOB SUM(SAL) JOB_ROLLUP DEPTNO_ROLLUP
---------- --------- ---------- ---------- -------------
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
10 8750 1
20 ANALYST 6000
20 CLERK 1100
20 MANAGER 2975
20 10075 1
30 MANAGER 2850
30 SALESMAN 5600
30 8450 1
27275 1 1
12 rows selected.
Notice how the grouping() function returns a 1 when a row represents a rollup of that column. I've used decode to return 1 or NULL (would normally return 0 or 1 -- the zeroes made the output hard to read). Using this fact, it becomes trivial to find the rollup rows. You'll find though that when you goto put this into a procedure:ask_tom@OSI1.WORLD> variable x refcursor
ask_tom@OSI1.WORLD> set autoprint on
ask_tom@OSI1.WORLD> begin
2 open :x for
3 select deptno, job, sum(sal),
4 decode(grouping(job),1,1,NULL) job_rollup,
5 decode(grouping(deptno),1,1,NULL) deptno_rollup
6 from emp
7 where sal > :P_SAL
8 group by rollup(deptno,job);
9 end;
10 /
begin
*
ERROR at line 1:
ORA-06550: line 8, column 11:
PLS-00201: identifier 'ROLLUP' must be declaredORA-06550: line 3, column 1:
PL/SQL: SQL Statement ignored
It fails. We currently must use dynamic sql to execute this type of query. It would look like this:ask_tom@OSI1.WORLD> begin
2 open :x for
3 'select deptno, job, sum(sal),
4 decode(grouping(job),1,1,NULL) job_rollup,
5 decode(grouping(deptno),1,1,NULL) deptno_rollup
6 from emp
7 where sal > :BV1
8 group by rollup(deptno,job)' using :P_SAL;
9 end;
10 /
PL/SQL procedure successfully completed.
DEPTNO JOB SUM(SAL) JOB_ROLLUP DEPTNO_ROLLUP
---------- --------- ---------- ---------- -------------
10 CLERK 1300
10 MANAGER 2450
10 PRESIDENT 5000
10 8750 1
20 ANALYST 6000
20 CLERK 1100
20 MANAGER 2975
20 10075 1
30 MANAGER 2850
30 SALESMAN 5600
30 8450 1
27275 1 1
12 rows selected.
ask_tom@OSI1.WORLD>
Notice we can still support bind variables and all using the USING clause. This is as efficient as a "static" ref cursor.