Preciso consultar um banco de dados SQL para encontrar todos os valores distintos de uma coluna e preciso de um valor arbitrário de outra coluna. Por exemplo, considere a seguinte tabela com duas colunas, chave e valor:
key value
=== =====
one test
one another
one value
two goes
two here
two also
three example
Desejo recuperar uma linha de amostra, escolhida arbitrariamente, de cada chave distinta, talvez obtendo essas três linhas:
key value
=== =====
one test
two goes
three example
Como posso formular essa consulta em SQL?
A consulta mais fácil de escrever é para MySQL (sem configurações ANSI estritas). Ele usa a construção não padronizada:
Na versão recente (5.7 e 8.0+) onde as configurações estritas e
ONLY_FULL_GROUP_BY
são o padrão, você pode usar aANY_VALUE()
função, adicionada em 5.7:Para outros SGBDs, que possuem funções de janela (como Postgres, SQL-Server, Oracle, DB2), você pode usá-los assim. A vantagem é que você também pode selecionar outras colunas no resultado (além do
key
andvalue
):Para versões mais antigas do acima e para qualquer outro DBMS, uma maneira geral que funciona em quase todos os lugares. Uma desvantagem é que você não pode selecionar outras colunas com essa abordagem. Outra é que funções agregadas gostam
MIN()
eMAX()
não funcionam com alguns tipos de dados em alguns DBMSs (como bit, texto, blobs):O PostgreSQL tem um
DISTINCT ON
operador especial não padrão que também pode ser usado. O opcionalORDER BY
é para selecionar qual linha de cada grupo deve ser selecionada:Para MS-SQl Server:
Da mesma forma, você pode ter rownum = 2 para seu segundo conjunto de resultados
Semelhante à resposta aceita, mas em vez de min() ou max() você pode usar array_agg()
Você pode, opcionalmente, ordenar valores dentro do array para selecionar o maior ou o menor deles:
(verificado no PostgreSQL)
Se você usa PostgreSQL, também existe uma função agregada chamada
first()
(oulast()
) de uma extensão chamada first_last_agg , que faz exatamente isso: retornando o primeiro valor (em qualquer ordem definida):você pode usar a consulta abaixo: