Antworten:
Warum müssen Sie nach HAVING Spalten erstellen, die Sie selbst erstellt haben (z. B. "1 als Zahl auswählen"), und nicht WO in MySQL?
WHERE
wird vor angewendet GROUP BY
, HAVING
wird nach angewendet (und kann nach Aggregaten filtern).
In der Regel können Sie Aliase in keiner dieser Klauseln verweisen, sondern MySQL
ermöglicht Referenzierung SELECT
Ebene Aliase GROUP BY
, ORDER BY
und HAVING
.
Und gibt es irgendwelche Nachteile, anstatt "WHERE 1" zu tun (Schreiben der gesamten Definition anstelle eines Spaltennamens)?
Wenn Ihr berechneter Ausdruck keine Aggregate enthält, ist es WHERE
höchstwahrscheinlich effizienter , ihn in die Klausel einzufügen.
Alle anderen Antworten auf diese Frage trafen nicht den entscheidenden Punkt.
Angenommen, wir haben eine Tabelle:
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
Und haben 10 Zeilen mit ID und Wert von 1 bis 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);
Versuchen Sie die folgenden 2 Abfragen:
SELECT `value` v FROM `table` WHERE `value`>5; -- Get 5 rows
SELECT `value` v FROM `table` HAVING `value`>5; -- Get 5 rows
Sie erhalten genau die gleichen Ergebnisse. Sie können sehen, dass die HAVING-Klausel ohne die GROUP BY-Klausel funktionieren kann.
Hier ist der Unterschied:
SELECT `value` v FROM `table` WHERE `v`>5;
Fehler # 1054 - Unbekannte Spalte 'v' in 'where-Klausel'
SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows
Mit der WHERE-Klausel kann eine Bedingung eine beliebige Tabellenspalte verwenden, jedoch keine Aliase oder Aggregatfunktionen. Mit der HAVING-Klausel kann eine Bedingung eine ausgewählte (!) Spalte, einen Alias oder eine Aggregatfunktion verwenden.
Dies liegt daran, dass die WHERE-Klausel Daten vor der Auswahl filtert, die HAVING-Klausel jedoch die resultierenden Daten nach der Auswahl filtert.
Wenn Sie also die Bedingungen in die WHERE-Klausel einfügen, ist dies effizienter, wenn Sie viele, viele Zeilen in einer Tabelle haben.
Versuchen Sie EXPLAIN, um den Hauptunterschied zu sehen:
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 |
+----+-------------+-------+-------+---------------+-------+---------+------+------+-------------+
Sie können sehen, ob WHERE oder HAVING den Index verwendet, aber die Zeilen sind unterschiedlich.
SELECT value, COUNT(*) frequency FROM table GROUP BY value HAVING frequency > 10
...HAVING clause can use both column and alias.
zu ...HAVING clause can use either column or alias.
und Wechsel ...WHERE clause will be more effective
zu...WHERE clause will be more efficient
Der Hauptunterschied besteht darin, dass WHERE
nicht für gruppierte Elemente (wie z. B. SUM(number)
) verwendet werden kannHAVING
kann, ist.
Der Grund dafür ist das WHERE
geschehen ist , bevor die Gruppierung und HAVING
erfolgt nach der Gruppierung erfolgt.
HAVING
wird verwendet, um nach Aggregationen in Ihrem zu filtern GROUP BY
.
So suchen Sie beispielsweise nach doppelten Namen:
SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
Diese 2 fühlen sich wie die ersten an, da beide verwendet werden, um über eine Bedingung zum Filtern von Daten zu sprechen. Obwohl wir in jedem Fall "Haben" anstelle von "Wo" verwenden können, gibt es Fälle, in denen wir "Wo" nicht anstelle von "Haben" verwenden können. Dies liegt daran, dass in einer Auswahlabfrage 'wobei' Daten vor 'Auswahl' filtert, während 'Daten nach' Auswahl 'gefiltert werden. Wenn wir also Aliasnamen verwenden, die sich nicht in der Datenbank befinden, kann 'wo' sie nicht identifizieren, aber 'haben' kann.
Beispiel: Lassen Sie die Tabelle Student student_id, Name, Geburtstag, Adresse enthalten. Angenommen, der Geburtstag ist vom Typ Datum.
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
und vollständig HAVING
.
WHERE filtert vor der Gruppierung von Daten und HAVING filtert nach der Gruppierung von Daten. Dies ist eine wichtige Unterscheidung; Zeilen, die durch eine WHERE- Klausel entfernt werden, werden nicht in die Gruppe aufgenommen. Dies könnte die berechneten Werte ändern, was wiederum (= als Ergebnis) beeinflussen könnte, welche Gruppen basierend auf der Verwendung dieser Werte in der HAVING- Klausel gefiltert werden .
Und weiter,
HAVING ist WHERE so ähnlich, dass die meisten DBMS sie als dasselbe behandeln, wenn kein GROUP BY angegeben ist. Trotzdem sollten Sie diese Unterscheidung selbst treffen. Verwenden Sie HAVING nur in Verbindung mit GROUP BY- Klauseln. Verwenden Sie WHERE für die Standardfilterung auf Zeilenebene.
Auszug aus: Forta, Ben. "Sams bringt sich SQL in 10 Minuten bei (5. Ausgabe) (Sams bringt sich selbst bei ...)."
Haben wird nur mit Aggregation verwendet, aber wo mit Nicht-Aggregationsanweisungen.