sql >> Base de Datos >  >> RDS >> Oracle

sql order by con una cláusula de selección interna y grupo por resumen

Podrías hacer algo como esto. No tengo sus datos de entrada, así que usé SCOTT.EMP en su lugar.

Note algunas cosas. Agrupé por JOB , y usé GROUPING(JOB) ambos en SELECT (para agregar la etiqueta TOTAL para la fila de resumen) y en ORDER BY . Dado que reutilizo el nombre de la columna JOB en SELECT (para la columna de salida), en ORDER BY Debo tener cuidado de calificar el nombre de la columna JOB (para que quede claro, me refiero a la columna de la tabla de entrada, no a la columna en SELECT - cuál sería el valor predeterminado si los nombres de columna en ORDER BY no estaban calificados). La necesidad de calificar los nombres de las columnas en ORDER BY , luego, me obligó a crear un alias para la tabla en FROM cláusula (de lo contrario, habría tenido que llevar el nombre completo de la tabla a todas partes).

Usando el GROUPING función en SELECT (en lugar de NVL ) es particularmente importante si JOB puede ser null . No quieres el grupo para null trabajo a ser etiquetado como TOTAL - solo quiere eso para la fila acumulada. Este punto confunde incluso a muchos programadores muy avanzados.

Muestro como puedes decidir "manualmente" el orden:PRESIDENT primero, luego MANAGER y luego todos los demás trabajos (ordenados alfabéticamente). Si tiene el orden de prioridad guardado en algún lugar, por ejemplo en una tabla, puede unirse a esa tabla y usar la columna de orden en lugar del "manual" CASE expresión en mi consulta.

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