Oracle
 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 или SQL Developer (с „изпълни като скрипт“),

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. SQL тип данни, който да се използва при вмъкване на пари

  2. ORA-01840:входната стойност не е достатъчно дълга за формат на дата в Oracle Вмъкване с помощта на Select

  3. Oracle:тригер за автоматично нарастване.

  4. Изтрийте редове, за да имате максимум x реда на група в таблицата на Oracle

  5. Инсталиране на Oracle 12c Enterprise Edition на Windows 7