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

Oracle 11g でのクエリ結果の転置

    あなたは近いです - あなたが望むのは UNPIVOT の組み合わせです および PIVOT :

    with T AS (
      select 1 as element, 1.1 as reading1, 1.2 as reading2, 1.3 as reading3 from dual union all
      select 2 as element, 2.1 as reading1, 2.2 as reading2, 2.3 as reading3 from dual union all
      select 3 as element, 3.1 as reading1, 3.2 as reading2, 3.3 as reading3 from dual 
    )
    select * from (
      select * from t
      unpivot (reading_value
        for reading_name in ("READING1", "READING2", "READING3")
        )
      pivot(max(reading_value) for element in (1,2,3)
      )
    )
    order by reading_name
    

    このクエリ

    • を変換します reading1、reading2、reading3 を別々のに (名前は reading_name に入ります 、値を reading_value に );これにより、(element,reading_name) ごとに 1 行が得られます
    • を変換します 1、2*、3 (要素の値 ) 列 '1'、'2'、'3' に。これにより、reading_name ごとに 1 つの行が得られます

    更新

    要素のリストが実行時までわからない場合 (たとえば、ユーザーがそれらを選択するオプションを持っているため)、より動的なアプローチが必要です。指定された要素のリストに対して SQL ステートメントを動的に作成し、sys_refcursor を使用する 1 つのソリューションを次に示します。 結果セットのために。

    -- setup table
    create table T AS 
      select 1 as element, 1.1 as reading1, 1.2 as reading2, 1.3 as reading3 from dual union all
      select 2 as element, 2.1 as reading1, 2.2 as reading2, 2.3 as reading3 from dual union all
      select 3 as element, 3.1 as reading1, 3.2 as reading2, 3.3 as reading3 from dual ;  
    /
    
    declare
      l_Elements dbms_sql.Number_Table;
    
      function pivot_it(p_Elements in dbms_sql.Number_Table) 
        return sys_refcursor is
          l_SQL CLOB := empty_clob();
          l_Result sys_refcursor;
        begin
          l_SQL := '
            select * from (
              select * from t 
                unpivot (reading_value
                  for reading_name in ("READING1", "READING2", "READING3")
                )
              pivot(max(reading_value) for element in (';
          for i in 1 .. p_Elements.count
                  loop
                      l_SQL := l_SQL || to_char(p_Elements(i)) || ',';
                    end loop;
          -- remove trailing ','                
          l_SQL := regexp_replace(l_SQL, ',$');                
          l_SQL := l_SQL || ')
            )
          )';
          dbms_output.put_line(l_SQL);
          open l_Result for l_SQL;
          return l_Result;
      end;      
    begin
      l_Elements(1) := 1;
      l_Elements(2) := 2;
      -- uncomment this line to get all 3 elements
      -- l_Elements(3) := 3;
      -- return the cursor into a bind variable (to be used in the host environment)
      :p_Cursor := pivot_it(l_Elements);  
    end;
    

    この関数から返されたカーソルをどのように使用するかは、使用している環境によって異なります。SQL/Plus では、カーソルを印刷するだけでよく、ほとんどのプログラミング言語の Oracle バインディングはすぐに使用できます。

    注意: このコードは、提供されたデータに対して機能しますが、基本的なエラー チェックさえ行われていません。動的 SQL は常に SQL インジェクション攻撃のターゲットになる可能性があるため、これは特に重要です。




    1. PHP:BLOBを画像ファイルに変換します

    2. Doctrine2はFROM句のSELECTを認識しません

    3. データベース設計は、教師、レッスン、および学生の編成にどのように役立ちますか?

    4. SQLServerデータベースパフォーマンス監視プラットフォームが提供する必要のある上位5つの機能