2017-09-04 11 views
0

ユーザーから指定された特定のテーブルの列をピボットする必要があります。 問題は、各テーブルからピボットする列の数が動的であることです。 以下のコードは、テーブルから列の名前を取得します。SQLでネストされた選択を使用するとピボットが機能しない

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') 

上記のコードは、以下の形式の列を返す:

col1, col2 

私はこの要件のためのピボットを使用して、カラムを旋回するために、以下のコードで上記のコードを接続しなければなりません。

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; 

コードは、この場合、正常に動作しますが、列名を取得するには、SELECT文で 'COL2'、 'col1の' 交換する際に、システムが次のエラーがスローされます。

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; 
---------------- 

この問題を解決する方法はありますか?

+2

listaggによって返されるSTRING(単数)は、IN()内で使用するもののように見えるかもしれませんが、真実はそのようには機能しません。単一の文字列 "'col1'、 'col2'"を文字列 'col1、col2'のペアとして解釈するには、「動的SQL」を作成する必要があります。 –

答えて

0

ピボット・テーブルへの入力として動的式を直接追加することはできません。 PL/SQLブロックを介して変数内のテーブルのすべての列を取得し、次のように試すことができます。 Oracle Pivot Tableの機能によって予測されます。

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; 
    /
関連する問題