Oracle
 sql >> Database >  >> RDS >> Oracle

sql order by con una clausola select interna e group by rollup

Potresti fare qualcosa del genere. Non ho i tuoi dati di input, quindi ho usato SCOTT.EMP invece.

Nota alcune cose. Ho raggruppato per JOB e ho usato GROUPING(JOB) entrambi in SELECT (per aggiungere l'etichetta TOTAL per la riga di riepilogo) e in ORDER BY . Poiché riutilizzo il nome della colonna JOB in SELECT (per la colonna di output), in ORDER BY Devo fare attenzione a qualificare il nome della colonna JOB (per chiarire mi riferisco alla colonna della tabella di input, non alla colonna in SELECT - quale sarebbe l'impostazione predefinita se i nomi delle colonne in ORDER BY non erano qualificati). La necessità di qualificare i nomi delle colonne in ORDER BY , quindi, mi ha costretto ad alias la tabella in FROM clausola (altrimenti avrei dovuto portare il nome completo della tabella ovunque).

Usando il GROUPING funzione in SELECT (anziché NVL ) è particolarmente importante se JOB può essere null . Non vuoi che il gruppo sia null lavoro da etichettare TOTAL - lo vuoi solo per la riga di rollup. Questo punto confonde anche molti programmatori molto avanzati.

Ti mostro come puoi decidere "manualmente" l'ordine:PRESIDENT prima, poi MANAGER , quindi tutti gli altri lavori (in ordine alfabetico). Se hai l'ordine di priorità salvato da qualche parte, ad esempio in una tabella, puoi unirti a quella tabella e utilizzare la colonna di ordinamento invece del "manuale" CASE espressione nella mia query.

select case grouping(job) when 0 then job else 'TOTAL' end as job
     , sum(sal) as total_salary
from   scott.emp e
group  by rollup(job)
order  by grouping(e.job)       -- to get the total in the last row
        , case e.job when 'PRESIDENT' then 1 when 'MANAGER' then 2 end
        , e.job
;

JOB       TOTAL_SALARY
--------- ------------
PRESIDENT         5000
MANAGER           8275
ANALYST           6000
CLERK             4150
SALESMAN          5600
TOTAL            29025