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.
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