Aprendi algo simples sobre SQL outro dia:
SELECT c FROM myTbl GROUP BY C
Tem o mesmo resultado que:
SELECT DISTINCT C FROM myTbl
O que eu estou curioso é que existe algo diferente na maneira como um mecanismo SQL processa o comando, ou eles são realmente a mesma coisa?
Pessoalmente, prefiro a sintaxe distinta, mas tenho certeza de que é mais um hábito do que qualquer outra coisa.
EDIT: Esta não é uma pergunta sobre agregados. O uso de GROUP BY
com funções agregadas é entendido.
SELECT c FROM myTbl UNION SELECT c FROM myTbl
obter e obter o mesmo resultado ... Mas por que complicar as coisas quando SELECT DISTINCT é tão fácil?GROUP BY
é muito anterior a 'SELECT' eDISTINCT
segue a seleção.DISTINCT
resulta na seleção do campo - ou seja, o valor aparecerá no conjunto de resultados.GROUP BY
pode efetivamente remover duplicatas sem realmente selecionar o campo. Isso é um tanto irrelevante na maioria dos casos, mas pode ser exatamente o que você deseja nos outros. Se você acabar usandoGROUP BY
no lugar deDISTINCT
, provavelmente é necessário um comentário explicativo no código.Respostas:
A resposta da MusiGenesis é funcionalmente a correta em relação à sua pergunta, conforme indicado; o SQL Server é inteligente o suficiente para perceber que, se você estiver usando "Agrupar por" e não usar nenhuma função agregada, o que você realmente quer dizer é "Distinto" - e, portanto, gera um plano de execução como se você tivesse simplesmente usado "Distinct . "
No entanto, acho importante observar a resposta de Hank - o tratamento descuidado de "Group By" e "Distinct" pode levar a algumas dicas perniciosas, se você não tomar cuidado. Não é totalmente correto dizer que "essa não é uma pergunta sobre agregados", porque você está perguntando sobre a diferença funcional entre duas palavras-chave de consulta SQL, uma das quais deve ser usada com agregados e a outra não.
Um martelo pode funcionar para parafusar algumas vezes, mas se você tem uma chave de fenda à mão, por que se preocupar?
(para os fins desta analogia,
Hammer : Screwdriver :: GroupBy : Distinct
escrew => get list of unique values in a table column
)fonte
GROUP BY
permite usar funções agregadas, comoAVG
,MAX
,MIN
,SUM
, eCOUNT
. Por outro lado,DISTINCT
apenas remove duplicatas.Por exemplo, se você possui vários registros de compras e deseja saber quanto foi gasto por cada departamento, faça algo como:
Isso fornecerá uma linha por departamento, contendo o nome do departamento e a soma de todos os
amount
valores em todas as linhas para esse departamento.fonte
DISTINCT
+ funções agregadas? assim:select distinct department, SUM(amount) from ...
Não há diferença (no SQL Server, pelo menos). Ambas as consultas usam o mesmo plano de execução.
http://sqlmag.com/database-performance-tuning/distinct-vs-group
Talvez lá é a diferença, se houver sub-consultas envolvidas:
http://blog.sqlauthority.com/2007/03/29/sql-server-difference-between-distinct-and-group-by-distinct-vs-group-by/
Não há diferença (estilo Oracle):
http://asktom.oracle.com/pls/asktom/f?p=100:11ieved::::P11_QUESTION_ID:32961403234212
fonte
Qual é a diferença de um mero ponto de vista da funcionalidade de remoção duplicada
Além do fato de que
DISTINCT
, diferentemente ,GROUP BY
permite agregar dados por grupo (que já foi mencionado por muitas outras respostas), a diferença mais importante na minha opinião é o fato de as duas operações "acontecerem" em duas etapas muito diferentes na ordem lógica. de operações que são executadas em umaSELECT
instrução .Aqui estão as operações mais importantes:
FROM
(incluindoJOIN
,APPLY
etc.)WHERE
GROUP BY
(pode remover duplicatas)HAVING
SELECT
DISTINCT
(pode remover duplicatas)UNION
,INTERSECT
,EXCEPT
(Pode remover duplicados)ORDER BY
OFFSET
LIMIT
Como você pode ver, a ordem lógica de cada operação influencia o que pode ser feito com ela e como ela influencia as operações subseqüentes. Em particular, o fato de a
GROUP BY
operação "acontecer antes" daSELECT
operação (a projeção) significa que:1. Não depende da projeção
Um exemplo em que não é útil depender da projeção é se você deseja calcular as funções da janela em valores distintos:
Quando executado no banco de dados Sakila , isso gera:
O mesmo não poderia ser alcançado com
DISTINCT
facilidade:Essa consulta está "errada" e produz algo como:
Não é isso que queríamos. A
DISTINCT
operação "acontece depois" da projeção, portanto não podemos mais removerDISTINCT
classificações porque a função da janela já foi calculada e projetada. Para usarDISTINCT
, teríamos que aninhar essa parte da consulta:Nota lateral: Nesse caso em particular, também poderíamos usar
DENSE_RANK()
2. Ele não pode usar nenhum valor da projeção
Uma das desvantagens do SQL é sua verbosidade às vezes. Pelo mesmo motivo que vimos antes (a ordem lógica das operações), não podemos "facilmente" agrupar por algo que estamos projetando.
Este é SQL inválido:
Isso é válido (repetindo a expressão)
Isso também é válido (aninhando a expressão)
Eu escrevi sobre esse tópico com mais profundidade em uma postagem no blog
fonte
WHERE
mas talvezGROUP BY
). De qualquer forma, acho uma péssima idéia e sugiro nunca usar esse recurso por motivos de portabilidade e manutenção. "De repente", não funcionará mais, por exemplo, ao criar um atalho para uma função agregada ou função de janela.never using that feature for portability and maintenance reasons
!! concordou 100% ... e agora estou curtindo seu blog também, ótimo trabalho. Felicidades.Use
DISTINCT
se você quiser apenas remover duplicatas. UseGROUPY BY
se você deseja aplicar operadores de agregação (MAX
,SUM
,GROUP_CONCAT
, ..., ou de umaHAVING
cláusula).fonte
Espero que exista a possibilidade de diferenças sutis em sua execução. Eu verifiquei os planos de execução para duas consultas funcionalmente equivalentes ao longo destas linhas no Oracle 10g:
A operação intermediária é um pouco diferente: "HASH GROUP BY" vs. "HASH UNIQUE", mas os custos estimados etc. são idênticos. Em seguida, eu os executei com o rastreamento ativado e a contagem real de operações foi a mesma para ambos (exceto que o segundo não precisou fazer nenhuma leitura física devido ao armazenamento em cache).
Mas acho que, como os nomes das operações são diferentes, a execução seguiria caminhos de código um tanto diferentes e isso abre a possibilidade de diferenças mais significativas.
Eu acho que você deve preferir a sintaxe DISTINCT para esse fim. Não é apenas um hábito, indica mais claramente o objetivo da consulta.
fonte
Para a consulta que você postou, eles são idênticos. Mas para outras consultas que podem não ser verdadeiras.
Por exemplo, não é o mesmo que:
fonte
Li todos os comentários acima, mas não vi ninguém apontar para a principal diferença entre Agrupar por e Distinto além do bit de agregação.
Distinct retorna todas as linhas e as desduplica, enquanto Group By desduplicata as linhas conforme elas são lidas pelo algoritmo, uma a uma.
Isso significa que eles podem produzir resultados diferentes!
Por exemplo, os códigos abaixo geram resultados diferentes:
Se houver 10 nomes na tabela em que 1 deles é uma duplicata de outro, a primeira consulta retornará 10 linhas, enquanto a segunda consulta retornará 9 linhas.
A razão é o que eu disse acima para que eles possam se comportar de maneira diferente!
fonte
Name
na segunda consulta, adistinct
palavra - chave se aplica às colunasName
e à suaROW_NUMBER()
coluna naselect
cláusula da primeira consulta. Se você também agrupasse a primeira coluna na segunda consulta, as consultas teriam retornado os mesmos resultados.order of execution
das cláusulas SQL que é (de um modo geral)FROM and ON (joins)
,WHERE
,GROUP BY
,HAVING
,SELECT
,DISTINCT
,ORDER BY
,LIMIT / OFFSET / TOP
de modo que a segunda consulta os nomes são reduzidos em número por grupo e mais tarde o row_number () é aplicada, resultando em uma fileira por nome exclusivo. Na primeira consulta, row_number () é aplicado antes que o distinto seja aplicado e, devido à natureza da função row_number (), cada linha obtém um número inteiro exclusivo; portanto, cada linha é retornada, mesmo que haja valores de nome repetidos.Se você usar DISTINCT com várias colunas, o conjunto de resultados não será agrupado como em GROUP BY e você não poderá usar funções agregadas com DISTINCT.
fonte
Eles têm semânticas diferentes, mesmo que tenham resultados equivalentes em seus dados específicos.
fonte
GROUP BY tem um significado muito específico que é distinto (heh) da função DISTINCT.
GROUP BY faz com que os resultados da consulta sejam agrupados usando a expressão escolhida, as funções agregadas podem ser aplicadas e elas atuarão em cada grupo, e não no conjunto de resultados inteiro.
Aqui está um exemplo que pode ajudar:
Dada uma tabela que se parece com isso:
Esta consulta:
Produzirá resultados como este:
O que é obviamente muito diferente do uso do DISTINCT. Se você deseja agrupar seus resultados, use GROUP BY, se você quiser apenas uma lista exclusiva de uma coluna específica, use DISTINCT. Isso dará ao seu banco de dados a chance de otimizar a consulta para suas necessidades.
fonte
Por favor, não use GROUP BY quando você quer dizer DISTINCT, mesmo que funcione da mesma forma. Suponho que você esteja tentando economizar milissegundos de consultas e preciso ressaltar que o tempo do desenvolvedor é de magnitude superior ao do computador.
fonte
Se você estiver usando um GROUP BY sem nenhuma função agregada, internamente ele será tratado como DISTINCT, portanto, neste caso, não haverá diferença entre GROUP BY e DISTINCT.
Mas quando você recebe a cláusula DISTINCT, é melhor usá-la para encontrar seus registros exclusivos, porque o objetivo do GROUP BY é obter agregação.
fonte
agrupar por é usado em operações agregadas - como quando você deseja obter uma contagem de Bs discriminada pela coluna C
distinto é o que parece - você obtém linhas únicas.
No sql server 2005, parece que o otimizador de consultas é capaz de otimizar a diferença nos exemplos simplistas que eu executei. Não sei se você pode contar com isso em todas as situações.
fonte
Nessa consulta em particular, não há diferença. Mas, é claro, se você adicionar alguma coluna agregada, precisará usar o agrupar por.
fonte
Na perspectiva do Teradata :
Do ponto de vista do conjunto de resultados, não importa se você usa DISTINCT ou GROUP BY no Teradata. O conjunto de respostas será o mesmo.
Do ponto de vista do desempenho, não é o mesmo.
Para entender o que afeta o desempenho, você precisa saber o que acontece no Teradata ao executar uma instrução com DISTINCT ou GROUP BY.
No caso de DISTINCT, as linhas são redistribuídas imediatamente sem que ocorra qualquer pré-agregação, enquanto no caso de GROUP BY, em uma primeira etapa, é feita uma pré-agregação e somente então os valores exclusivos são redistribuídos nos AMPs.
Não pense agora que o GROUP BY é sempre melhor do ponto de vista do desempenho. Quando você tem muitos valores diferentes, a etapa de pré-agregação do GROUP BY não é muito eficiente. O Teradata precisa classificar os dados para remover duplicatas. Nesse caso, pode ser melhor primeiro a redistribuição, ou seja, use a instrução DISTINCT. Somente se houver muitos valores duplicados, a instrução GROUP BY provavelmente será a melhor escolha, pois somente quando a etapa de deduplicação ocorrer, após a redistribuição.
Em resumo, DISTINCT x GROUP BY em Teradata significa:
GRUPO POR -> para muitas duplicatas DISTINCT -> nenhuma ou apenas algumas duplicatas. Às vezes, ao usar DISTINCT, você fica sem espaço em spool em um AMP. O motivo é que a redistribuição ocorre imediatamente, e a inclinação pode fazer com que os AMPs fiquem sem espaço.
Se isso acontecer, você provavelmente terá uma chance melhor com o GROUP BY, pois as duplicatas já foram removidas em uma primeira etapa e menos dados são movidos pelos AMPs.
fonte
Teradata
?Do ponto de vista do 'SQL the language', as duas construções são equivalentes e qual delas você escolhe é uma daquelas escolhas de 'estilo de vida' que todos temos que fazer. Eu acho que há um bom argumento para DISTINCT ser mais explícito (e, portanto, é mais atencioso com a pessoa que herdará seu código etc.), mas isso não significa que a construção GROUP BY seja uma opção inválida.
Eu acho que esse 'GROUP BY é para agregados' é a ênfase errada. As pessoas devem estar cientes de que a função definida (MAX, MIN, COUNT, etc) pode ser omitida para que eles possam entender a intenção do codificador quando isso ocorre.
O otimizador ideal reconhecerá construções SQL equivalentes e sempre escolherá o plano ideal de acordo. Para o mecanismo SQL de sua escolha na vida real, você deve testar :)
PS observe que a posição da palavra-chave DISTINCT na cláusula select pode produzir resultados diferentes, por exemplo, contraste:
fonte
Você só percebe isso porque está selecionando uma única coluna.
Tente selecionar dois campos e veja o que acontece.
O Group By deve ser usado assim:
O que mostraria a soma de todas as transações para cada pessoa.
fonte
Eu sei que é um post antigo. Mas acontece que eu tive uma consulta que usou group apenas para retornar valores distintos ao usar essa consulta nos relatórios do toad e do oracle tudo funcionou bem, quero dizer um bom tempo de resposta. Quando migramos do Oracle 9i para 11g, o tempo de resposta no Toad foi excelente, mas, no relato, demorou cerca de 35 minutos para concluir o relatório ao usar a versão anterior, demorou cerca de 5 minutos.
A solução foi alterar o grupo e usar DISTINCT e agora o relatório é executado em cerca de 30 segundos.
Espero que isso seja útil para alguém com a mesma situação.
fonte
Em termos de uso, GROUP BY é usado para agrupar as linhas que você deseja calcular. DISTINCT não fará nenhum cálculo. Não mostrará linhas duplicadas.
Eu sempre usei DISTINCT se quiser apresentar dados sem duplicatas.
Se eu quiser fazer cálculos como resumir a quantidade total de mangas, usarei GROUP BY
fonte
A maneira como eu sempre entendi é que usar o distinto é o mesmo que agrupar por todos os campos selecionados na ordem em que foram selecionados.
ou seja:
é o mesmo que:
fonte
A eficiência funcional é totalmente diferente. Se você deseja selecionar apenas "valor de retorno", exceto o duplicado, usar distinto é melhor do que agrupar por. Como "agrupar por" inclui (classificação + remoção), "distinto" inclui (remoção)
fonte
No Hive (HQL), agrupar por pode ser muito mais rápido que distinto, porque o primeiro não exige a comparação de todos os campos da tabela. Consulte https://sqlperformance.com/2017/01/t-sql-queries/surprises-assumptions-group-by-distinct .
fonte
Às vezes, eles podem fornecer os mesmos resultados, mas devem ser usados em diferentes sentidos / casos. A principal diferença está na sintaxe.
Observe minuciosamente o exemplo abaixo.
DISTINCT
é usado para filtrar o conjunto duplicado de valores. (6, cs, 9.1) e (1, cs, 5.5) são dois conjuntos diferentes. Então,DISTINCT
ele exibirá as duas linhas enquantoGROUP BY Branch
exibirá apenas um conjunto.Às vezes, os resultados que podem ser alcançados por
GROUP BY
cláusula não são possíveis comDISTINCT
sem a utilização de cláusulas ou condições extras. Por exemplo, no caso acima.Para obter o mesmo resultado,
DISTINCT
você deve passar todos os nomes de coluna naGROUP BY
cláusula como abaixo. Então veja a diferença sintática. Você deve ter conhecimento sobre todos os nomes de colunas para usar aGROUP BY
cláusula nesse caso.Também notei
GROUP BY
exibe os resultados em ordem crescente por padrão, o queDISTINCT
não ocorre. Mas não tenho certeza disso. Pode ser diferente em relação ao fornecedor.Fonte: https://dbjpanda.me/dbms/languages/sql/sql-syntax-with-examples#group-by
fonte
Geralmente, podemos usar
DISTINCT
para eliminar as duplicatas na coluna específica da tabela.Exemplo:
fonte
Não há diferença significativa entre agrupar por e cláusula distinta, exceto o uso de funções agregadas. Ambos podem ser usados para distinguir os valores, mas se no ponto de vista do desempenho, agrupar por é melhor. Quando uma palavra-chave distinta é usada, internamente, é usada uma operação de classificação que pode ser visualizada no plano de execução.
Experimente um exemplo simples
Declarar @tmpresult table (ID tinyint)
Inserir em @tmpresult Selecionar 5 União tudo Selecionar 2 União tudo Selecionar 3 União tudo Selecionar 4
Selecionar ID diferente de @tmpresult
fonte