Oracle
 sql >> Base de données >  >> RDS >> Oracle

sql order by avec une clause select interne et group by rollup

Vous pourriez faire quelque chose comme ça. Je n'ai pas vos données d'entrée, j'ai donc utilisé SCOTT.EMP à la place.

Remarquez quelques choses. J'ai regroupé par JOB , et j'ai utilisé GROUPING(JOB) les deux dans SELECT (pour ajouter le libellé TOTAL pour la ligne récapitulative) et dans ORDER BY . Depuis que je réutilise le nom de colonne JOB dans SELECT (pour la colonne de sortie), dans ORDER BY Je dois faire attention à qualifier le nom de la colonne JOB (pour être clair, je fais référence à la colonne de la table d'entrée, pas à la colonne dans SELECT - qui serait la valeur par défaut si les noms de colonne dans ORDER BY n'étaient pas qualifiés). La nécessité de qualifier les noms de colonnes dans ORDER BY , puis, m'a forcé à aliaser la table dans le FROM clause (sinon j'aurais dû porter le nom complet de la table partout).

Utilisation du GROUPING fonction dans SELECT (plutôt que NVL ) est particulièrement important si JOB peut être null . Vous ne voulez pas le groupe pour null tâche à étiqueter TOTAL - vous ne voulez que cela pour la ligne de cumul. Ce point confond même beaucoup de programmeurs très avancés.

Je montre comment vous pouvez "manuellement" décider de l'ordre :PRESIDENT d'abord, puis MANAGER , puis tous les autres travaux (par ordre alphabétique). Si vous avez enregistré l'ordre de priorité quelque part, par exemple dans une table, vous pouvez vous joindre à cette table et utiliser la colonne de tri au lieu du "manuel" CASE expression dans ma requête.

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