Why don't PIVOT clause works with aggregate TRIP of 11g function?

Hi all!

I'm really confused as to what is considered an aggregate function in the context of the PIVOT clause in 11 g.

I've been playing with a lot of things related to collections lately and it took birth in an aside:
CREATE TABLE TEST_COLL
(
   NODE_ID    VARCHAR2(15 CHAR) NOT NULL,
   NODE_VALUE VARCHAR2(45 CHAR) NOT NULL,
   NODE_LEVEL NUMBER(1)         NOT NULL 
);

CREATE OR REPLACE TYPE TREE_NODE AS OBJECT 
(
   NODE_KEY  VARCHAR2( 15 CHAR),
   NODE_NAME VARCHAR2(127 CHAR)
);

CREATE OR REPLACE TYPE TREE_NODES AS TABLE OF TREE_NODE NOT NULL;
At this point, I'm sure we can all agree that the application
SELECT NODE_LEVEL, 
       CAST(COLLECT(TREE_NODE(NODE_ID, NODE_VALUE)) AS TREE_NODES) AS NODES
  FROM TEST_COLL
 GROUP BY NODE_LEVEL;
perfectly valid is that the function of COLLECTION is an aggregation function according to the [Official Documentation | http://docs.oracle.com/cd/E11882_01/server.112/e10592/functions031.htm#i1271564]
But then, one of the two following queries should work
SELECT CAST(REGION_NODES     AS TREE_NODES) AS REGIONS,
       CAST(DEPARTMENT_NODES AS TREE_NODES) AS DEPARTMENTS,
       CAST(AREA_NODES       AS TREE_NODES) AS AREAS,
       CAST(CENTRE_NODES     AS TREE_NODES) AS CENTRES
  FROM (SELECT NODE_LEVEL, TREE_NODE(NODE_ID, NODE_VALUE) AS NODE
          FROM TREE_COLL
       )
 PIVOT (COLLECT(NODE) FOR NODE_LEVEL IN (1 AS REGION_NODES,
                                         2 AS DEPARTMENT_NODES,
                                         3 AS AREA_NODES,
                                         4 AS CENTRE_NODES
                                        )
       );

or (better)

SELECT REGION_NODES     AS REGIONS,
       DEPARTMENT_NODES AS DEPARTMENTS,
       AREA_NODES       AS AREAS,
       CENTRE_NODES     AS CENTRES
  FROM (SELECT NODE_LEVEL, TREE_NODE(NODE_ID, NODE_VALUE) AS NODE
          FROM TREE_COLL
       )
 PIVOT (CAST(COLLECT(NODE) AS TREE_NODES) FOR NODE_LEVEL IN (1 AS REGION_NODES,
                                                             2 AS DEPARTMENT_NODES,
                                                             3 AS AREA_NODES,
                                                             4 AS CENTRE_NODES
                                                            )
       );
Yet, these two with
ORA-56902: expect aggregate function inside pivot operation
Study further, I found the same behavior when you use the aggregate function in the PIVOT XMLAGG clause.

Is this normal? And if this is the case, is there another way to get the result that I expected?

My version is
SQL> SELECT BANNER FROM V$VERSION;

BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE    11.2.0.3.0      Production
TNS for 64-bit Windows: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
Thanks in advance
Best regards

Philippe

Most likely a bug. But you can work around it by using any other aggregate for this group is composed of a single line and apply collect a rotated value. Yes, the cost is double aggregation. And also there is another cost - you must create the service card member other aggreations such as MAX/MIN, etc. will not work:

CREATE OR REPLACE TYPE TREE_NODE AS OBJECT
(
   NODE_KEY  VARCHAR2( 15 CHAR),
   NODE_NAME VARCHAR2(127 CHAR),
   map member function f return varchar2
)
/

Type created.

CREATE OR REPLACE TYPE BODY TREE_NODE AS
  map member function f return varchar2 is
  begin
     return NODE_NAME;
  end f;
end;
/

Type body created.

CREATE OR REPLACE TYPE TREE_NODES AS TABLE OF TREE_NODE NOT NULL
/

Type created.

SQL> select  *
  2    from  test_coll
  3  /

NODE_ID NODE_VALUE NODE_LEVEL
------- ---------- ----------
1       A                   1
2       B                   2
3       C                   3
4       D                   4
5       E                   1
6       F                   2
7       G                   3
8       H                   4

8 rows selected.

SQL> 

Now:

SELECT CAST(COLLECT(REGION_NODES)     AS TREE_NODES) AS REGIONS,
       CAST(COLLECT(DEPARTMENT_NODES) AS TREE_NODES) AS DEPARTMENTS,
       CAST(COLLECT(AREA_NODES)       AS TREE_NODES) AS AREAS,
       CAST(COLLECT(CENTRE_NODES)     AS TREE_NODES) AS CENTRES
  FROM (
        SELECT  ROWID RID,
                NODE_LEVEL,
                TREE_NODE(NODE_ID, NODE_VALUE) AS NODE
          FROM  TEST_COLL
       )
 PIVOT (MAX(NODE) FOR NODE_LEVEL IN (
                                     1 AS REGION_NODES,
                                     2 AS DEPARTMENT_NODES,
                                     3 AS AREA_NODES,
                                     4 AS CENTRE_NODES
                                    )
       )
/

REGIONS(NODE_KEY, NODE_NAME)                         DEPARTMENTS(NODE_KEY, NODE_NAME)                     AREAS(NODE_KEY, NODE_NAME)                           CENTRES(NODE_KEY, NODE_NAME)
---------------------------------------------------- ---------------------------------------------------- ---------------------------------------------------- ----------------------------------------------------
TREE_NODES(TREE_NODE('1', 'A'), TREE_NODE('5', 'E')) TREE_NODES(TREE_NODE('6', 'F'), TREE_NODE('2', 'B')) TREE_NODES(TREE_NODE('7', 'G'), TREE_NODE('3', 'C')) TREE_NODES(TREE_NODE('8', 'H'), TREE_NODE('4', 'D'))

SQL> 

SY.

Tags: Database

Similar Questions

Maybe you are looking for