MySQL Cláusula GROUP BY e HAVING com exemplos
⚡ Resumo Inteligente
As cláusulas SQL GROUP BY e HAVING transformam linhas detalhadas em relatórios resumidos. GROUP BY agrupa linhas que compartilham os mesmos valores em uma única linha por grupo, enquanto HAVING filtra esses grupos após a aplicação de funções de agregação como COUNT.

O que é a cláusula GROUP BY em SQL?
A cláusula GROUP BY é um comando SQL usado para agrupar linhas que possuem os mesmos valoresÉ escrito dentro da instrução SELECT e normalmente é usado em conjunto com funções de agregação para gerar relatórios resumidos a partir do banco de dados.
É isso que ele faz: ele resume os dados armazenadas no banco de dados. Consultas que contêm a cláusula GROUP BY são chamadas de consultas agrupadas e retornam uma única linha para cada item agrupado.
GRUPO SQL POR Sintaxe
Agora que o propósito da cláusula está claro, observe a sintaxe de uma consulta agrupada básica.
SELECT statements... GROUP BY column_name1[, column_name2, ...] [HAVING condition];
AQUI
- "Instruções SELECT…"é o padrão" SELEÇÃO SQL consulta de comando.
- "GROUP BY nome_coluna1“ é a cláusula que realiza o agrupamento”ping com base em column_name1.
- "[, nome_da_coluna2, …]“ é opcional e representa outros nomes de coluna quando o grupoping é feito em mais de uma coluna.
- "[TER condição]O operador “ é opcional e serve para restringir as linhas afetadas pela cláusula GROUP BY. É semelhante ao operador “ Cláusula WHERE, exceto que é aplicado após o grupoping.
Grouping Usando uma única coluna
A maneira mais rápida de ver o efeito da cláusula GROUP BY do SQL é comparar uma consulta sem agrupamento com uma consulta com agrupamento. Comece com uma consulta simples que retorne todas as entradas de gênero na tabela de membros.
SELECT `gender` FROM `members`;
| gênero |
|---|
| Feminino |
| Feminino |
| Masculino |
| Feminino |
| Masculino |
| Masculino |
| Masculino |
| Masculino |
| Masculino |
Nove linhas são retornadas, e cada valor se repete. Suponha que queiramos os valores únicos para gênero. A consulta abaixo adiciona a cláusula GROUP BY.
SELECT `gender` FROM `members` GROUP BY `gender`;
Executando o script acima em MySQL Workbench contra o myflixdb nos dá os seguintes resultados.
| gênero |
|---|
| Feminino |
| Masculino |
Observe que apenas duas linhas foram retornadas, pois a tabela contém apenas dois tipos de gênero. A cláusula GROUP BY agrupou todos os membros do gênero "Masculino" e retornou uma única linha para eles, e fez o mesmo com os membros do gênero "Feminino".
Grouping Utilizando múltiplas colunas
Grouping Agrupar em uma única coluna costuma ser muito impreciso para um relatório completo. A função GROUP BY aceita uma lista de colunas separadas por vírgulas, e a combinação de seus valores define cada grupo.
Suponha que desejamos uma lista de valores de `category_id` de filmes e os respectivos anos em que os filmes foram lançados. Observe primeiro o resultado desta consulta simples.
SELECT `category_id`, `year_released` FROM `movies`;
| Categoria ID | ano_de lançamento |
|---|---|
| 1 | 2011 |
| 2 | 2008 |
| NULL | 2008 |
| NULL | 2010 |
| 8 | 2007 |
| 6 | 2007 |
| 6 | 2007 |
| 8 | 2005 |
| NULL | 2012 |
| 7 | 1920 |
| 8 | NULL |
| 8 | 1920 |
As linhas destacadas mostram que o resultado contém duplicados. Executar a mesma consulta com GROUP BY remove esses duplicados.
SELECT `category_id`, `year_released` FROM `movies` GROUP BY `category_id`, `year_released`;
Executando o script acima em MySQL A análise do Workbench com o banco de dados myflixdb nos fornece os seguintes resultados, conforme mostrado abaixo.
| Categoria ID | ano_de lançamento |
|---|---|
| NULL | 2008 |
| NULL | 2010 |
| NULL | 2012 |
| 1 | 2011 |
| 2 | 2008 |
| 6 | 2007 |
| 7 | 1920 |
| 8 | 1920 |
| 8 | 2005 |
| 8 | 2007 |
A cláusula GROUP BY opera tanto em category_id quanto em year_released para identificar único linhas. As duas linhas duplicadas da categoria 6 em 2007 foram unidas em uma só.
Regra prática: Se o ID da categoria for o mesmo, mas o ano de lançamento for diferente, a linha será considerada única. Se o ID da categoria e o ano de lançamento forem iguais em mais de uma linha, as linhas serão consideradas duplicadas e apenas uma delas será exibida.
Grouping e funções agregadas
Remover duplicados é útil, mas o verdadeiro poder do agrupamento reside na sua capacidade de lidar com duplicados.ping aparece quando é emparelhado com funções agregadasUma função agregada calcula um valor para cada grupo: COUNT conta as linhas, SUM soma os valores e AVG, MIN e MAX descrevem a dispersão.
Suponha que desejemos o número total de membros masculinos e femininos no banco de dados. O script abaixo faz isso.
SELECT `gender`, COUNT(`membership_number`) FROM `members` GROUP BY `gender`;
Executando o script acima em MySQL A análise do Workbench com o banco de dados myflixdb nos fornece os seguintes resultados.
| gênero | CONTAR(`número_de_membros`) |
|---|---|
| Feminino | 3 |
| Masculino | 6 |
As linhas são agrupadas por cada valor de gênero único, e o número de linhas em cada grupo é contado pela função de agregação COUNT. Os nove registros de membros são consolidados em duas linhas de resumo.
Restringindo os resultados da consulta usando a cláusula HAVING
GroupingNem sempre é desejável incluir valores em todas as linhas de uma tabela. Às vezes, o relatório precisa ser restrito a um critério específico, e essa é a função da cláusula HAVING.
Suponha que queiramos saber todos os anos de lançamento para a categoria de filme com ID 8. O script abaixo realiza essa tarefa.
SELECT * FROM `movies` GROUP BY `category_id`, `year_released` HAVING `category_id` = 8;
Executando o script acima em MySQL A análise do Workbench com o banco de dados myflixdb nos fornece os seguintes resultados, conforme mostrado abaixo.
| id_do_filme | título | diretor | ano_de lançamento | Categoria ID |
|---|---|---|---|---|
| 9 | Honey mooners | John Schultz | 2005 | 8 |
| 5 | As filhinhas do papai | NULL | 2007 | 8 |
Apenas os filmes com ID de categoria 8 foram mantidos pela condição HAVING.
Atenção: MySQL A partir da versão 5.7, o modo ONLY_FULL_GROUP_BY é ativado por padrão. Nesse modo, a consulta SELECT * com uma cláusula GROUP BY é rejeitada, pois movie_id, title e director não são agrupados nem agregados. Em produção, nomeie as colunas agrupadas explicitamente, por exemplo. SELECT category_id, year_released FROM movies GROUP BY category_id, year_released HAVING category_id = 8;
WHERE vs HAVING vs GROUP BY vs ORDER BY
Os iniciantes frequentemente confundem essas quatro cláusulas, porque todas elas moldam o conjunto de resultados. A diferença reside em quando MySQL Aplica-se a elas: WHERE é executado antes do agrupamento das linhas, HAVING é executado depois e ORDER BY é executado por último.
| Cláusula | O que ele faz | Quando ele funciona | Aceita funções agregadas |
|---|---|---|---|
| ONDE | Filtra linhas individuais antes de qualquer grupo.ping. | Antes de AGRUPAR POR | Não |
| GROUP BY | Agrupa as linhas que compartilham os mesmos valores em uma única linha por grupo. | Depois ONDE | Não aplicável |
| TENDO | Filtra os grupos produzidos por GROUP BY. | Após GROUP BY | Sim, por exemplo, HAVING COUNT(*) > 2 |
| ORDENAR POR | Ordena as linhas que sobreviveram às cláusulas anteriores. | Sobrenome | Sim, um alias agregado pode ser ordenado. |
A consequência prática é uma questão de desempenho. Filtrar com WHERE remove as linhas anteriores ao grupo.ping O trabalho começa, portanto, uma condição que não depende de um resultado agregado pertence à cláusula WHERE em vez de HAVING.
