Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Obtendo valores relacionados às linhas max e min no Oracle


Isso é facilmente resolvido com funções analíticas. Como você pode ver, há dois funcionários ganhando o salário máximo no DEPT 20; esse é um detalhe importante, pois algumas soluções comuns para esse tipo de problema deixam passar essa informação.
SQL> select ename
  2             , deptno
  3             , sal
  4  from (
  5      select ename
  6             , deptno
  7             , sal
  8             , max (sal) over (partition by deptno) max_sal
  9             , min (sal) over (partition by deptno) min_sal
 10      from emp
 11      )
 12  where sal = max_sal
 13  or    sal = min_sal
 14  order by deptno, sal
 15  /

ENAME          DEPTNO        SAL
---------- ---------- ----------
KISHORE            10       1300
SCHNEIDER          10       5000
CLARKE             20        800
RIGBY              20       3000
GASPAROTTO         20       3000
HALL               30        950
LIRA               30       3750
TRICHLER           50       3500
FEUERSTEIN         50       4500

9 rows selected.

SQL>

Ops, perdi um detalhe importante sobre o formato do resultado. Meus dados não cabem na saída solicitada, pois há dois funcionários ganhando o salário máximo. Portanto, esta consulta, que admito ser um pouco estranha, nos fornece o layout necessário. O MIN() nos nomes dos funcionários retorna a ordem alfabética:
SQL> select
  2         deptno
  3         , max (case when sal = min_sal then min_sal else null end ) as min_sal
  4         , min (case when sal = min_sal then ename else null end ) as min_name
  5         , max (case when sal = max_sal then max_sal else null end ) as max_sal
  6         , min (case when sal = max_sal then ename else null end ) as max_name
  7  from (
  8      select ename
  9             , deptno
 10             , sal
 11             , max (sal) over (partition by deptno) max_sal
 12             , min (sal) over (partition by deptno) min_sal
 13      from emp
 14      )
 15  where sal = max_sal
 16  or    sal = min_sal
 17  group by deptno
 18  order by deptno
 19  /

    DEPTNO    MIN_SAL MIN_NAME      MAX_SAL MAX_NAME
---------- ---------- ---------- ---------- ----------
        10       1300 KISHORE          5000 SCHNEIDER
        20        800 CLARKE           3000 GASPAROTTO
        30        950 HALL             3750 LIRA
        50       3500 TRICHLER         4500 FEUERSTEIN

SQL>

Eu não gosto dessa solução. A maioria dos conjuntos de dados conterá esses conflitos e precisamos reconhecê-los. Filtrar o resultado com base em alguns critérios não relacionados para ajustar um layout de relatório de Procusto é enganoso. Eu preferiria um layout de relatório que refletisse todo o conjunto de dados. Em última análise, depende da finalidade comercial que a consulta atende. E, claro, o cliente sempre tem razão 8-)