Oracle
 sql >> Baza danych >  >> RDS >> Oracle

konwertuj tabelę sql w formie macierzy

To może być dla Ciebie pomocne. Użyłem CASE WHEN THEN END bloki do osiągnięcia 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

AKTUALIZUJ

Nie mogłem znaleźć sposobu na napisanie tego w jednym zapytaniu. Po kilku analizach znalazłem to .

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

Utworzono funkcję, która dynamicznie tworzy SQL i zwraca SYS_REFCURSOR . Można to uruchomić w SQL*Plus lub SQL Developer (z opcją „uruchom jako skrypt”),

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



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Jak używać kursora referencji Oracle z języka C# ODP.NET jako parametru ReturnValue bez użycia funkcji lub procedury przechowywanej?

  2. używając pl/sql jak otworzyć katalog?

  3. Czy źle rozumiem sprzężenia?

  4. Wyrocznia. Brak słowa kluczowego podczas korzystania z instrukcji case. Błąd 00905

  5. Różne daty Oracle 11g z TOAD