pivot does not work when using a nested select in

2019-08-26 09:48发布

I have a requirement to pivot the columns of a particular table specified from a user. the problem is the number of columns from each table to pivot is dynamic. so the code below gets the name of the columns from the table.

SELECT DISTINCT 
                LISTAGG('''' || column_name || '''', ',') 
                    WITHIN GROUP (ORDER BY column_name) AS temp_in_statement 
                FROM (SELECT DISTINCT column_name FROM all_tab_columns WHERE table_name = 'DIM_XYZ')

the code above returns the columns in the following format:

col1, col2

I have to use a pivot for this requirement and plug the code above in the code below in order to pivot the columns.

SELECT * FROM
(
  SELECT table_name, column_name
  FROM ALL_TAB_COLUMNS
  WHERE
      table_name = 'DIM_XYZ'

)
PIVOT
(
  MIN(column_name)
  FOR column_name IN ( 

-- values added manually 

 'col1','col2'

-- values added manually 


    )
)
ORDER BY table_name;

The code works fine in this case but when replacing 'col1','col2' by the select statement to retrieve columns names the system throws the following error:

ORA-00936: missing expression
00936. 00000 -  "missing expression"
*Cause:    
*Action:
Error at Line: 39 Column: 40

CODE:

SELECT * FROM
(
  SELECT table_name, column_name
  FROM ALL_TAB_COLUMNS
  WHERE
      table_name = 'DIM_XYZ'

)
PIVOT
(
  MIN(column_name)
  FOR column_name IN ( 

--code below does not work when plugged in the statement above
              SELECT DISTINCT 
                LISTAGG('''' || column_name || '''', ',') 
                    WITHIN GROUP (ORDER BY column_name) AS temp_in_statement 
                FROM (SELECT DISTINCT column_name FROM all_tab_columns WHERE table_name = 'DIM_XYZ')
 --code above does not work
    )
)
ORDER BY table_name;
----------------

do you guys have any idea how to solve this problem?

标签: sql oracle pivot
1条回答
家丑人穷心不美
2楼-- · 2019-08-26 10:33

You cannot directly add dynamic expressions as an input to Pivot table, You can try something like this where we retrieve all the columns of the table in a variable via a PL/SQL Block and then pass it in a way to the expected by the Oracle Pivot Table Functionality.

SET serveroutput ON;


    DECLARE 
    sqlquery VARCHAR(32767);
    cols VARCHAR2(32767);
    BEGIN

      SELECT listagg('''' || column_name || '''',   ',') within
      GROUP(
      ORDER BY column_name)
      INTO cols
      FROM
        (SELECT DISTINCT column_name
         FROM all_tab_columns
         WHERE TABLE_NAME = 'TABLE_NAME')
      ;

      sqlquery := '      
    SELECT * FROM
    (
      SELECT table_name, column_name
      FROM ALL_TAB_COLUMNS
      WHERE
          table_name = ''TABLE_NAME''
    )
    PIVOT
    (
      MIN(column_name)
      FOR column_name IN ( 
            ''||cols||''
        )
      )
      ORDER BY table_name';

      DBMS_OUTPUT.PUT_LINE(sqlquery);

      EXECUTE IMMEDIATE sqlquery;

    END;
    /
查看更多
登录 后发表回答