sql >> データベース >  >> RDS >> Oracle

Oracle Dynamic Pivoting

    実行時に列が不明な結果に動的SQLを使用することは、他の特定のRDMBSと比較して、Oracleでは少し面倒です。

    出力のレコードタイプはまだ不明であるため、事前に定義することはできません。

    Oracle 11gでは、1つの方法は、ピボットされた結果で一時テーブルを生成する名前のないプロシージャを使用することです。

    次に、その一時テーブルから結果を選択します。

    declare
      v_sqlqry clob;
      v_cols clob;
    begin
      -- Generating a string with a list of the unique names
      select listagg(''''||CCL||''' as "'||CCL||'"', ', ') within group (order by CCL)
      into v_cols
      from 
      (
        select distinct CCL
        from tableA
      );
    
      -- drop the temporary table if it exists
      EXECUTE IMMEDIATE 'DROP TABLE tmpPivotTableA';
      EXCEPTION WHEN OTHERS THEN IF SQLCODE != -942 THEN RAISE; END IF;
    
      -- A dynamic SQL to create a temporary table 
      -- based on the results of the pivot
      v_sqlqry := '
        CREATE GLOBAL TEMPORARY TABLE tmpPivotTableA
        ON COMMIT PRESERVE ROWS AS
        SELECT * 
        FROM (SELECT ID, CCL, Flag FROM TableA) src 
        PIVOT (MAX(Flag) FOR (CCL) IN ('||v_cols||')) pvt';
    
      -- dbms_output.Put_line(v_sqlqry); -- just to check how the sql looks like
      execute immediate v_sqlqry;
    
    end;
    /
    
    select * from tmpPivotTableA;
    

    返品:

    ID  adam john rob terry
    --  ---- ---- --- -----
    1   x    x    x
    2        x      
    

    db<>fiddleここでテストを見つけることができます

    Oracle 11gでは、使用する別のクールなトリック(Anton Schefferによって作成された)がこのブログにあります。ただし、ピボット関数を追加する必要があります。
    ソースコードはこのzipにあります

    その後、SQLは次のように単純になります。

    select * from 
    table(pivot('SELECT ID, CCL, Flag FROM TableA'));
    

    db<>fiddleここでテストを見つけることができます



    1. MySQLINクエリで順序を維持する

    2. テーブルをパラメータとしてSQLサーバーUDFに渡します

    3. floatデータ型とdecimalデータ型の違い

    4. MySQLのJSON_CONTAINS()の例