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

SQLテーブルを行列形式に変換します

    これはあなたに役立つかもしれません。 CASE WHEN THEN ENDを使用しました PIVOTを達成するためのブロック 。

    SELECT USERS.USER_NAME
      , MAX(COALESCE(TEST.USER1, 0)) USER1
      , MAX(COALESCE(TEST.USER2, 0)) USER2
      , MAX(COALESCE(TEST.USER3, 0)) USER3
      , MAX(COALESCE(TEST.USER7, 0)) USER7
    FROM (
      SELECT DISTINCT USER_NAME 
      FROM (
          SELECT USER_NAME FROM TEST
          UNION ALL
          SELECT M_USER FROM TEST
        )
      ) USERS
        LEFT OUTER JOIN (
          SELECT
              USER_NAME
              , M_USER
              , CASE WHEN M_USER = 'user 1' THEN TOTAL ELSE 0 END AS USER1
              , CASE WHEN M_USER = 'user 2' THEN TOTAL ELSE 0 END AS USER2
              , CASE WHEN M_USER = 'user 3' THEN TOTAL ELSE 0 END AS USER3
              , CASE WHEN M_USER = 'user 7' THEN TOTAL ELSE 0 END AS USER7
          FROM TEST
        ) TEST ON USERS.USER_NAME = TEST.USER_NAME
    GROUP BY USERS.USER_NAME
    ORDER BY USERS.USER_NAME
    

    更新

    単一のクエリでこれを書く方法を見つけることができませんでした。分析の結果、これ が見つかりました。 。

    CREATE OR REPLACE FUNCTION GETUSERS RETURN SYS_REFCURSOR AS
      QUERY VARCHAR2(32767);
      RC SYS_REFCURSOR;
    BEGIN
    
      QUERY := 'SELECT USERS.USER_NAME ';
    
      FOR TMP IN (SELECT DISTINCT UPPER(REPLACE(USER_NAME, ' ', '')) USER_NAME FROM (SELECT USER_NAME FROM TEST UNION ALL SELECT M_USER FROM TEST) ORDER BY USER_NAME)
      LOOP
        QUERY := QUERY || '  , MAX(COALESCE(TEST.' || TMP.USER_NAME || ' , 0)) ' || TMP.USER_NAME;
      END LOOP;
    
      QUERY := QUERY || ' FROM ( ';
      QUERY := QUERY || '  SELECT DISTINCT USER_NAME ';
      QUERY := QUERY || '  FROM ( ';
      QUERY := QUERY || '      SELECT USER_NAME FROM TEST ';
      QUERY := QUERY || '      UNION ALL ';
      QUERY := QUERY || '      SELECT M_USER FROM TEST ';
      QUERY := QUERY || '    ) ';
      QUERY := QUERY || '  ) USERS ';
      QUERY := QUERY || '    LEFT OUTER JOIN ( ';
    
      QUERY := QUERY || ' SELECT USER_NAME';
      FOR TMP IN (SELECT DISTINCT USER_NAME, REPLACE(USER_NAME, ' ', '') USER_COL_NM FROM (SELECT USER_NAME FROM TEST UNION ALL SELECT M_USER FROM TEST))
      LOOP
        QUERY := QUERY || ', CASE WHEN M_USER = ''' || TMP.USER_NAME
          || ''' THEN TOTAL ELSE 0 END AS ' || TMP.USER_COL_NM ;
      END LOOP;
      QUERY := QUERY || ' FROM TEST';
    
      QUERY := QUERY || '    ) TEST ON USERS.USER_NAME = TEST.USER_NAME ';
      QUERY := QUERY || 'GROUP BY USERS.USER_NAME ';
      QUERY := QUERY || 'ORDER BY USERS.USER_NAME';
    
      OPEN RC FOR QUERY;
    
      RETURN RC;
    END;
    /
    

    SQLを動的に作成する作成された関数 SYS_REFCURSORを返します 。これは、SQL *PlusまたはSQLDeveloper(「スクリプトとして実行」を使用)で実行できます。

    VAR RC REFCURSOR;
    EXEC :RC := GETUSERS;
    PRINT RC
    



    1. 文字列上のOracleのOUTERJOIN(+)-Migration PostgreSQL

    2. SQLクエリとドロップダウンリスト

    3. 一部のテーブルを除いてFlywayタスクを実行する方法はありますか?

    4. to_char関数が原因でOracleの無効な数値