Risposte:
Perché è necessario posizionare colonne create dall'utente (ad esempio "seleziona 1 come numero") dopo AVERE e non DOVE in MySQL?
WHERE
viene applicato prima GROUP BY
, HAVING
viene applicato dopo (e può filtrare sugli aggregati).
In generale, è possibile fare riferimento alias in alcuno di queste clausole, ma MySQL
consente riferimento SELECT
alias livello in GROUP BY
, ORDER BY
e HAVING
.
E ci sono degli svantaggi invece di fare "WHERE 1" (scrivendo l'intera definizione invece del nome di una colonna)
Se la tua espressione calcolata non contiene alcun aggregato, inserirla nella WHERE
clausola molto probabilmente sarà più efficiente.
Tutte le altre risposte a questa domanda non hanno colpito il punto chiave.
Supponiamo di avere un tavolo:
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 hanno 10 righe con id e valore compresi tra 1 e 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);
Prova le seguenti 2 query:
SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows
SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows
Otterrai esattamente gli stessi risultati, puoi vedere che la clausola HAVING può funzionare senza la clausola GROUP BY.
Ecco la differenza:
SELECT `value` v FROM `table` WHERE `v`>5;
Errore n. 1054 - Colonna sconosciuta "v" in "clausola where"
SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows
La clausola WHERE consente a una condizione di utilizzare qualsiasi colonna della tabella, ma non può utilizzare alias o funzioni aggregate. La clausola HAVING consente a una condizione di utilizzare una colonna, un alias o una funzione aggregata selezionata.
Questo perché la clausola WHERE filtra i dati prima della selezione, ma la clausola HAVING filtra i dati risultanti dopo la selezione.
Quindi inserisci le condizioni nella clausola WHERE sarà più efficiente se hai molte molte righe in una tabella.
Prova EXPLAIN per vedere la differenza chiave:
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 |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
Puoi vedere WHERE o HAVING utilizza l'indice, ma le righe sono diverse.
SELECT value, COUNT(*) frequency FROM table GROUP BY value HAVING frequency > 10
...HAVING clause can use both column and alias.
per ...HAVING clause can use either column or alias.
e cambiare ...WHERE clause will be more effective
a...WHERE clause will be more efficient
La differenza principale è che WHERE
non può essere utilizzato su articoli raggruppati (come SUM(number)
) mentre HAVING
can.
Il motivo è l' WHERE
è fatto prima che il raggruppamento e HAVING
viene fatto dopo il raggruppamento è fatto.
HAVING
viene utilizzato per filtrare le aggregazioni nel tuo GROUP BY
.
Ad esempio, per verificare la presenza di nomi duplicati:
SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
Questi 2 saranno i primi come entrambi vengono usati per dire una condizione per filtrare i dati. Sebbene possiamo usare "avere" al posto di "dove" in ogni caso, ci sono casi in cui non possiamo usare "dove" invece di "avere". Questo perché in una query di selezione, "dove" filtra i dati prima di "seleziona" mentre "avendo" filtra i dati dopo "seleziona". Pertanto, quando utilizziamo nomi di alias che non si trovano effettivamente nel database, "dove" non è in grado di identificarli ma "possibilmente" può.
Esempio: lascia che la tabella Studente contenga student_id, nome, data di nascita, indirizzo. Supponi che la data di nascita sia di 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
.
DOVE filtra prima che i dati vengano raggruppati e HAVING filtra dopo che i dati sono stati raggruppati. Questa è una distinzione importante; le righe eliminate da una clausola WHERE non verranno incluse nel gruppo. Questo potrebbe cambiare i valori calcolati che, a loro volta (= come risultato) potrebbero influenzare quali gruppi vengono filtrati in base all'uso di tali valori nella clausola HAVING .
E continua
HAVING è così simile a DOVE che la maggior parte dei DBMS li tratta come la stessa cosa se non viene specificato GROUP BY . Tuttavia, dovresti fare tu stesso questa distinzione. Utilizzare HAVING solo in combinazione con le clausole GROUP BY . Utilizzare WHERE per il filtro standard a livello di riga.
Estratto da: Forta, Ben. "Sams Teach Yourself SQL in 10 Minutes (5th Edition) (Sams Teach Yourself ...).".
Avere viene utilizzato solo con aggregazione ma dove con istruzioni non di aggregazione Se si dispone di dove la parola lo inserisce prima dell'aggregazione (raggruppa per)