Това може да е полезно за вас. Използвал съм 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