Eu tenho uma tabela como esta:
ID | Val | Kind
----------------------
1 | 1337 | 2
2 | 1337 | 1
3 | 3 | 4
4 | 3 | 4
Quero fazer um SELECT
que retorne apenas a primeira linha de cada uma Val
, ordenando por Kind
.
Saída de amostra:
ID | Val | Kind
----------------------
2 | 1337 | 1
3 | 3 | 4
Como posso criar esta consulta?
oracle
greatest-n-per-group
BrunoLM
fonte
fonte
ORDER BY ID DESC
, mas isso não é relevante para a pergunta. Neste exemplo, eu não ligo.Respostas:
Esta solução também usa
keep
, masval
ekind
também pode ser simplesmente calculado para cada grupo sem uma subconsulta:dbfiddle aqui
KEEP… PRIMEIRO e KEEP… LAST são um recurso agregado específico do Oracle - você pode ler sobre isso aqui nos documentos do Oracle ou em ORACLE_BASE :
fonte
Use uma expressão de tabela comum (CTE) e uma função de janela / classificação / particionamento como ROW_NUMBER .
Essa consulta criará uma tabela na memória chamada ORDERED e adicionará uma coluna adicional de rn, que é uma sequência de números de 1 a N. A PARTITION BY indica que ele deve reiniciar em 1 sempre que o valor de Val for alterado e queremos solicitar linhas pelo menor valor de Kind.
A abordagem acima deve funcionar com qualquer RDBMS que tenha implementado a função ROW_NUMBER (). O Oracle possui algumas funcionalidades elegantes, conforme expressas na resposta da mik, que geralmente resultam em melhor desempenho do que esta resposta.
fonte
A solução da bilinkc funciona bem, mas eu pensei em jogar fora a minha também. Tem o mesmo custo, mas pode ser mais rápido (ou mais lento, não testei). A diferença é que ele usa o First_Value em vez de Row_Number. Como estamos interessados apenas no primeiro valor, na minha opinião, é mais direto.
Dados de teste.
Se você preferir, aqui está o equivalente CTE.
fonte
id
sejam únicas.Você pode usar
keep
para selecionar umid
de cada grupo:dbfiddle aqui
fonte
fonte