Mito T-SQL: Cláusula GROUP BY garante ordenação do result set
Publicado; 10/05/2012 Arquivado em: SQL T-SQL Mitos | Tags: Boas Práticas T-SQL, Mitos SQL Server, Mitos T-SQL, T-SQL Deixe um comentárioDe vez em quando alguém me questiona: é realmente necessário explicitar uma cláusula ORDER BY quando utilizo um GROUP BY? O GROUP BY não força o ordenamento da query?
A resposta que costumo deixar é “Não. GROUP BY não garante ordenação”. Isso é fato e o contrário é mito.
Vejamos alguns exemplos simples que comprovam essa questão.
use Northwind
go
— Esta query não retorna resultado ordenado
select o.ShipCountry, count(*) qt
from dbo.Orders o
group by o.ShipCountry
— Result set
— Plano de execução
Observe que no plano de execução não existe o operador SORT, responsável justamente por fazer a ordenação.
No segundo exemplo, a seguir, estou agrupando por duas colunas e deixando sem cláusula ORDER BY.
— Agrupando com duas colunas sem ORDER BY
select o.ShipCountry, o.ShipCity, count(*) qt
from dbo.Orders o
group by o.ShipCountry, o.ShipCity
Vamos agora observar o plano de execução para entendermos o que o otimizador fez.
Inicialmente nota-se que foi incluído um Sort, justamente porque estamos agrupando por mais de uma coluna. Mas qual o critério de ordenação nesse caso?
Veja que o otimizador escolheu ordenar de “forma contrária”: primeiro por cidade e depois por país. Portanto, o resultado não será o esperado, já que para esse exemplo, o natural é que os registros sejam listados na ordem Páis – Cidade.
Assim feito, só nos resta aplicar uma tradicional clásula ORDER BY para garantir a ordenação esperada pelo usuário.
select o.ShipCountry, o.ShipCity, count(*) qt
from dbo.Orders o
group by o.ShipCountry, o.ShipCity
order by o.ShipCountry, o.ShipCity
O plano de execução gerado é o mesmo, exceto que agora, para o operador Sort, o otimizador seguiu a ordem explicitada em ORDER BY.
Segue o result set:
Até o próximo post.