Warum müssen Sie selbst erstellte Spalten platzieren (zum Beispiel select 1 as "number"
) nach HAVING
und nicht WHERE
in MySQL?
Und gibt es irgendwelche Nachteile, anstatt WHERE 1
(Schreiben der gesamten Definition anstelle eines Spaltennamens)?
Warum müssen Sie nach HAVING Spalten platzieren, die Sie selbst erstellt haben (z. B. "1 als Zahl auswählen"), und nicht WO in MySQL?
WHERE
wird angewendet, bevor GROUP BY
, HAVING
wird nach angewendet (und kann nach Aggregaten filtern).
Im Allgemeinen können Sie in keiner dieser Klauseln auf Aliase verweisen, aber MySQL
ermöglicht das Verweisen auf Aliase der Ebene SELECT
in 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 höchstwahrscheinlich effizienter, ihn in die WHERE
-Klausel einzufügen.
Alle Antworten auf haben nicht den entscheidenden Punkt getroffen.
Angenommen, wir haben einen Tisch:
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 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 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 die Daten vor der Auswahl filtert, die HAVING-Klausel jedoch die resultierenden Daten nach der Auswahl filtert.
Setzen Sie die Bedingungen in die WHERE-Klausel, wenn Sie 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.
Der Hauptunterschied besteht darin, dass WHERE
nicht für gruppierte Elemente (wie SUM(number)
) verwendet werden kann, wohingegen HAVING
kann.
Der Grund ist, dass WHERE
fertig ist vor die Gruppierung und HAVING
fertig ist nach die Gruppierung erfolgt.
HAVING
wird verwendet, um nach Aggregationen in Ihrem GROUP BY
zu filtern.
Um beispielsweise nach doppelten Namen zu suchen:
SELECT Name FROM Usernames
GROUP BY Name
HAVING COUNT(*) > 1
Diese 2 fühlen sich genauso an wie die ersten, da beide verwendet werden, um über eine Bedingung zum Filtern von Daten zu sprechen. Obwohl wir ohnehin "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 "where" Daten vor "select" filtert, während "filter data" nach "select" steht. Wenn wir also Aliasnamen verwenden, die sich nicht in der Datenbank befinden, kann "where" sie nicht identifizieren, aber "having".
Beispiel: Lassen Sie die Tabelle Student student_id, name, birthday, address enthalten. Angenommen, der Geburtstag ist vom Typ date.
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.*/
WOBEI filtert, bevor Daten gruppiert werden, und MIT filtert, nachdem Daten gruppiert werden. Dies ist eine wichtige Unterscheidung; Zeilen, die durch eine WOBEI -Klausel entfernt werden, werden nicht in die Gruppe aufgenommen. Dies könnte die berechneten Werte ändern, was wiederum Auswirkungen darauf haben könnte, welche Gruppen basierend auf der Verwendung dieser Werte in der MIT -Klausel gefiltert werden.
Auszug aus: Forta, Ben. "Sams unterrichtet sich selbst SQL in 10 Minuten (4. Ausgabe) (Sams unterrichtet sich selbst ...).".
Wird nur mit Aggregation verwendet, aber wo mit Nichtaggregationsanweisungen Wenn Sie haben, wo Word es vor Aggregation legte