Função analítica Oracle 12c

Existe uma maneira de obter o valor correspondente X para um valor mínimo Y num dado conjunto de dados, no mesmo registo, usando funções analíticas Oracle, e sem usar um subquery?

por exemplo:

Se eu tiver o seguinte conjunto de dados "ds1":

Col1  Col2
A     1
B     2
C     3
D     4
E     4
A     10

normalmente, para encontrar o valor "A" no Col1, que corresponde ao valor mínimo "1" no Col2, eu escreveria a seguinte consulta:

select ds1.col1
     from ds1
          , (select min (col2) col2
                  from ds1) min_ds1
     where ds1.col2 = min_ds1.col2
/
Aqui está o código executado para tal teste. Caso:

### 1014.010, Start time is: 10/30/2019 11:39:35am

MYUN@MYDB-C1>>create table ds1 (col1 varchar2 (1), col2 number)
  2  /

Table created.
Elapsed: 00:00:00.01

MYUN@MYDB-C1>>insert into ds1 (col1, col2)
  2       select 'A', 1 from dual
  3       union all select 'B', 2 from dual
  4       union all select 'C', 3 from dual
  5       union all select 'D', 4 from dual
  6       union all select 'E', 4 from dual
  7       union all select 'A', 10 from dual
  8  /

6 rows created.
Elapsed: 00:00:00.02

MYUN@MYDB-C1>>commit
  2  /

Commit complete.
Elapsed: 00:00:00.01

MYUN@MYDB-C1>>col col1 format a10
MYUN@MYDB-C1>>select ds1.col1
  2       from ds1
  3            , (select min (col2) col2
  4                    from ds1) min_ds1
  5       where ds1.col2 = min_ds1.col2
  6  /

COL1
----------
A

1 row selected.
Elapsed: 00:00:00.01

MYUN@MYDB-C1>>drop table ds1
  2  /

Table dropped.
Elapsed: 00:00:00.03
The time now: 10/30/2019 11:39:36am
A minha pergunta é:

é possível derivar o valor " A " usando uma função analítica e sem necessitar de uma sub-função? Estou ciente de que posso usar a função analítica "ROW_NUMBER", ordenar o resultado na ordem por cláusula, tudo em um subquery e, em seguida, adicionar uma cláusula onde na consulta externa onde eu digo algo como" WHERE RN = 1", onde" RN " é o alias para a coluna no subquery onde a função ROW_NUMBER é usada.

Author: MT0, 2019-10-30

1 answers

Usar uma função de agregação com KEEP para obter os valores mínimos para outra coluna:

Configuração Do Oráculo:

create table ds1 ( col1, col2 ) AS
  select 'A', 1 from dual
  union all select 'B', 2 from dual
  union all select 'C', 3 from dual
  union all select 'D', 4 from dual
  union all select 'E', 4 from dual
  union all select 'F', 10 from dual;

Pesquisa De Agregação:

SELECT MIN( col1 ) KEEP ( DENSE_RANK FIRST ORDER BY col2 ) AS col1
FROM   ds1

Resultado:

| COL1 |
| :--- |
| A    |

Pesquisa Analítica:

Se quiser particularmente uma função analítica, então:

SELECT col1, col2
FROM   (
  SELECT ds1.*,
         DENSE_RANK() OVER ( ORDER BY col2 ASC ) AS rnk
  FROM   ds1
)
WHERE  rnk = 1

Isto tem uma sub-consulta, mas só há uma única tabela-scan.

Você pode facilmente integrá-lo em um enorme pesquisa:
WITH my_huge_query AS (
  <paste your huge query here>
)
SELECT *
FROM   (
  SELECT m.*,
         DENSE_RANK() OVER( ORDER BY col2 ASC ) AS rnk
  FROM   my_huge_query m
)
WHERE  rnk = 1

Resultado:

COL1 | COL2
:--- | ---:
A    |    1

db fiddle aqui

 5
Author: MT0, 2019-10-30 16:33:21