Respostas:
Por que você precisa colocar as colunas criadas por você mesmo (por exemplo, "selecione 1 como número") após HAVING e não WHERE no MySQL?
WHERE
é aplicado antes GROUP BY
, HAVING
é aplicado depois (e pode filtrar em agregados).
Em geral, você pode referenciar aliases em nenhuma dessas cláusulas, mas MySQL
permite referenciar SELECT
aliases de nível em GROUP BY
, ORDER BY
e HAVING
.
E existem desvantagens em vez de fazer "WHERE 1" (escrevendo a definição inteira em vez de um nome de coluna)
Se sua expressão calculada não contiver agregados, colocá-la na WHERE
cláusula provavelmente será mais eficiente.
Todas as outras respostas sobre esta questão não atingiram o ponto principal.
Suponha que temos uma tabela:
CREATE TABLE `table` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`value` int(10) unsigned NOT NULL,
PRIMARY KEY (`id`),
KEY `value` (`value`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
E tenha 10 linhas com o ID e o valor de 1 a 10:
INSERT INTO `table`(`id`, `value`) VALUES (1, 1),(2, 2),(3, 3),(4, 4),(5, 5),(6, 6),(7, 7),(8, 8),(9, 9),(10, 10);
Tente as 2 consultas a seguir:
SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows
SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows
Você obterá exatamente os mesmos resultados, poderá ver que a cláusula HAVING pode funcionar sem a cláusula GROUP BY.
Aqui está a diferença:
SELECT `value` v FROM `table` WHERE `v`>5;
Erro # 1054 - coluna desconhecida 'v' na 'cláusula where'
SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows
A cláusula WHERE permite que uma condição use qualquer coluna da tabela, mas não pode usar aliases ou funções agregadas. A cláusula HAVING permite que uma condição use uma coluna (!) Selecionada, alias ou uma função agregada.
Isso ocorre porque a cláusula WHERE filtra os dados antes da seleção, mas a cláusula HAVING filtra os dados resultantes após a seleção.
Portanto, coloque as condições na cláusula WHERE serão mais eficientes se você tiver muitas linhas em uma tabela.
Tente EXPLAIN para ver a principal diferença:
EXPLAIN SELECT `value` v FROM `table` WHERE `value`>5;
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
| 1 | SIMPLE | table | range | value | value | 4 | NULL | 5 | Using where; Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+------+--------------------------+
EXPLAIN SELECT `value` v FROM `table` having `value`>5;
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
| 1 | SIMPLE | table | index | NULL | value | 4 | NULL | 10 | Using index |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
Você pode ver WHERE ou HAVING usa índice, mas as linhas são diferentes.
SELECT value, COUNT(*) frequency FROM table GROUP BY value HAVING frequency > 10
...HAVING clause can use both column and alias.
para ...HAVING clause can use either column or alias.
e alterar ...WHERE clause will be more effective
para...WHERE clause will be more efficient
A principal diferença é que WHERE
não pode ser usado em itens agrupados (como SUM(number)
) enquanto HAVING
can.
O motivo é que WHERE
é feito antes do agrupamento e HAVING
é feito depois que o agrupamento é concluído.
HAVING
é usado para filtrar agregações no seu GROUP BY
.
Por exemplo, para verificar nomes duplicados:
SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
Esses 2 parecerão iguais aos primeiros, pois ambos são usados para dizer sobre uma condição para filtrar dados. Embora possamos usar 'ter' no lugar de 'onde', em qualquer caso, há casos em que não podemos usar 'onde' em vez de 'ter'. Isso ocorre porque, em uma consulta de seleção, 'onde' filtra os dados antes de 'selecionar' enquanto 'possui' filtrar dados após 'selecionar'. Portanto, quando usamos nomes alternativos que não estão realmente no banco de dados, 'onde' não pode identificá-los, mas 'tendo' pode.
Ex: deixe a tabela Aluno conter student_id, nome, data de nascimento, endereço. Suponha que aniversário seja do tipo data.
SELECT * FROM Student WHERE YEAR(birthday)>1993; /*this will work as birthday is in database.if we use having in place of where too this will work*/
SELECT student_id,(YEAR(CurDate())-YEAR(birthday)) AS Age FROM Student HAVING Age>20;
/*this will not work if we use ‘where’ here, ‘where’ don’t know about age as age is defined in select part.*/
WHERE
e HAVING
.
WHERE filtra antes dos dados serem agrupados e HAVING filtra depois que os dados são agrupados. Esta é uma distinção importante; linhas que são eliminadas por uma cláusula WHERE não serão incluídas no grupo. Isso pode alterar os valores calculados que, por sua vez (= como resultado), podem afetar quais grupos são filtrados com base no uso desses valores na cláusula HAVING .
E continua,
HAVING é tão semelhante a WHERE que a maioria dos DBMSs os trata como a mesma coisa se nenhum GROUP BY for especificado. No entanto, você mesmo deve fazer essa distinção. Use HAVING apenas em conjunto com as cláusulas GROUP BY . Use WHERE para filtragem no nível de linha padrão.
Trecho de: Forta, Ben. “Sams Ensina-se SQL em 10 Minutos (5ª Edição) (Sams Ensina-se ...).”.
Ter é usado apenas com agregação, mas onde com instruções de não agregação Se você tiver onde a palavra a coloca antes da agregação (agrupar por)