Eu vi a seguinte consulta MySQL que usa DISTINCT e GROUP BY juntos:
SELECT DISTINCT user_id, post_id, post_content FROM some_table GROUP BY post_id, user_id HAVING post_content LIKE "%abc%";
Aqui está um cenário para acompanhar a consulta: Cada usuário tem um id único, user_id
, e pode fazer várias postagens que são identificadas por um id único, post_id
. Cada postagem conteria algum texto.
Achei isso confuso (depois de vir de bancos de dados Oracle) e tive as seguintes perguntas:
- Qual é o significado de usar
GROUP BY
sem fazer nenhuma agregação? - Qual é o significado de alternar a ordem das colunas em
SELECT
vs emGROUP BY
? - Qual é o significado de omitir a terceira coluna de
GROUP BY
? - Por que
DISTINCT
usado junto comGROUP BY
? A operação distinta é executada depois que todos os agrupamentos são feitos no resultado final ou antes?
Comentários
Resposta
ad 1) Antigos bancos de dados mysql e quando você desabilita ONLY_FULL_GROUP_BY , você pode fazer esta consulta e se os post_content forem iguais, você notará, que mysql retorna um valor aleatório não determinístico .
ad 2) nenhum tipo de coisa
ad 3) programação lenta e ocorre um erro quando você ativa ONLY_FULL_GROUP_BY
anúncio 4) Não, ele exibiria todos os post_content que estão conectados ao user_id, post_id semelhante a adicionar post_content ao grupo por
Como Strawberry já disse, esta consulta não faz algum sentido
Resposta
A capacidade insana de permitir agrupamento parcial em versões mais antigas do MyS QL, deve ser um dos principais candidatos à confusão mais causada no setor de TI.
Dada a tabela:
CREATE TABLE t ( x int not null primary key , y int not null ); INSERT INTO t (x,y) VALUES (1,1),(1,2);
A declaração
SELECT x, y FROM t GROUP BY x
poderia significar (1,1) ou (1,2) e o MySQL retornaria aleatoriamente um desses. DISTINCT não importa neste caso, o resultado ainda é indeterminista.
O SQL92 requer que todas as colunas na cláusula select (exceto colunas agregadas e constantes) façam parte da cláusula GROUP BY.
O SQL99 afrouxou um pouco essa restrição e nos permitiu deixar de fora colunas do GROUP BY que são funcionalmente dependentes das colunas restantes. Ou seja,
CREATE TABLE t ( x int not null primary key , y int not null ); SELECT x, y FROM t GROUP by x
seria válido, pois y é f.d. of x
Surpreendentemente (para mim) a versão posterior do MySQL é a melhor da classe quando se trata de implementar a versão SQL99. Não o verifiquei recentemente, mas quando fiz o MySQL lidou bem com cenários bastante complicados, enquanto o PostgreSQL lidou apenas com os triviais.
Para responder às suas perguntas
1)
SELECT x, y FROM t GROUP BY x, y
significa que a combinação de x, y é um grupo. Em todas as situações possíveis, posso pensar nisso é o mesmo que:
SELECT DISTINCT x, y FROM t
Como eles são avaliados logicamente em momentos diferentes, pode haver algum caso extremo em que eles realmente sejam diferentes (não consigo pensar em nenhum)
2) Nenhum , a este respeito, eles são um conjunto de colunas, portanto não há ordem
3) Veja acima.
4) A ordem lógica de avaliação de uma consulta SQL é:
FROM, JOIN WHERE GROUP BY HAVING SELECT DISTINCT ORDER BY FETCH FIRST
então GROUP BY deve ser avaliado antes de DISTINCT. Não consigo pensar em uma situação em que isso importe.
Em sua consulta Suspeito que alguém obteve resultados confusos e tentou obter outro resultado usando DISTINCT. Provavelmente teve sorte (ou azar) de obter o resultado. esperado, então o DISTINCT ficou. O bug ainda está lá, porém
GROUP BY
não importa de forma alguma (exceto que nas versões antigas, implicava o mesmoORDER BY
. OSELECT
a ordem importa apenas na organização das colunas na saída.