Digamos que eu tenha a seguinte tabela
-----------------------------
| user_id | comment |
-----------------------------
| 2 | thats cool |
| 2 | awesome |
| 3 | i hate this |
| 3 | okay |
| 6 | this is weird |
| 6 | hello? |
| 6 | what is it |
| 9 | how are you |
| 16 | too slow |
| 16 | yes |
| 17 | alrighty |
-----------------------------
Como você pode selecionar uma linha por user_id
? Então meus resultados seriam:
-----------------------------
| user_id | comment |
-----------------------------
| 2 | thats cool |
| 3 | i hate this |
| 6 | this is weird |
| 9 | how are you |
| 16 | too slow |
| 17 | alrighty |
-----------------------------
Isso é possível com uma única consulta eficiente? Ou são subselecionados necessários? É possível usar de alguma forma DISTINCT
em uma única coluna?
É para isso que
GROUP BY
serve. Obtenha uma linha (por grupo). Nesse caso, ele mostrará todos osuser_id
valores distintos e para o restante das colunas, você pode (tem que) usar funções de agregação comoMIN()
,MAX()
,AVG()
,SUM()
pois você terá mais de um valor por grupo e apenas um poderá ser mostrado.O MySQL também permite a seguinte solução pouco ortodoxa, que retornará um comentário (mais ou menos aleatório) por usuário:
Esta última consulta não funcionará, mas gerará um erro se o
ONLY_FULL_GROUP_BY
modo (mais rigoroso) estiver ativado. Na versão 5.7 lançada recentemente, este modo é o padrão e uma nova função,ANY_VALUE()
, é fornecida. Para obter mais detalhes, consulte a página Manipulação do MySQLGROUP BY
. A consulta pode ser escrita agora:Observe que com a versão "não ortodoxa" ou usando a
ANY_VALUE()
função recente, se adicionarmos mais colunas naSELECT
lista, não é garantido que seus valores sejam da mesma linha, apenas de uma linha do mesmo grupo. A forma como são selecionados não é exatamente aleatória, depende do plano de execução e dos índices utilizados.