webentwicklung-frage-antwort-db.com.de

WO vs HABEN

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)?

238
baloo

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.

311
Quassnoi

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.

265
Fishdrowned

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.

61
David Brunelle

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
39
Kevin McKelvin

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.*/
7
Nuwantha

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 ...).".

2
snr

Wird nur mit Aggregation verwendet, aber wo mit Nichtaggregationsanweisungen Wenn Sie haben, wo Word es vor Aggregation legte

1
Hos Mercury