2010-05-25 4 views
196

Warum müssen Sie Spalten, die Sie selbst erstellen (z. B. select 1 as "number") nach HAVING und nicht WHERE in MySQL platzieren?WHERE vs HAVING

Und gibt es irgendwelche Nachteile statt WHERE 1 (Schreiben der gesamten Definition anstelle eines Spaltennamens)?

Antwort

270

Warum müssen Sie Spalten, die Sie selbst erstellt haben (z. B. "1 als Nummer auswählen") nach HAVING und nicht nach WHERE in MySQL platzieren?

WHERE vor GROUP BY angewendet wird HAVING nach angewendet (und Aggregate filtern können).

In der Regel können Sie Aliase in keiner dieser Klauseln verweisen, aber MySQL ermöglicht Referenzierung SELECT Ebene Aliase in GROUP BY, ORDER BY und HAVING.

Und gibt es irgendwelche Nachteile anstatt das zu tun „WHERE 1“ (die ganze Definition Schreiben anstelle eines Spaltenname)

Wenn Ihr berechneten Ausdruck keine Aggregate enthalten, in die WHERE setzen Klausel wird höchstwahrscheinlich effizienter sein.

55

Der Hauptunterschied ist, dass WHERE nicht auf gruppierten Artikel (wie SUM(number)) verwendet werden kann, während HAVING kann.

Der Grund ist die WHEREvor die Gruppierung erfolgt und HAVING wird nach die Gruppierung erfolgt getan.

38

HAVING wird verwendet, um Aggregationen in Ihrem GROUP BY zu filtern.

Zum Beispiel für doppelte Namen zu überprüfen:

SELECT Name FROM Usernames 
GROUP BY Name 
HAVING COUNT(*) > 1 
+1

Es ist wahr zu einigen erhalten. Sie können immer noch Ihr ganzes 'Where' in die having-Klausel einfügen. –

+0

Siehe auch http://stackoverflow.com/questions/2905292/where-vs-having#comment48406726_18710763 – Pacerier

211

Alle Antworten auf nicht den entscheidenden Punkt getroffen hat.

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 sowohl 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 zwei 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 - Unknown column 'v' in 'where clause'

SELECT `value` v FROM `table` HAVING `v`>5; -- Get 5 rows 

WHERE-Klausel eine Bedingung erfordert eine Spalte in einer Tabelle zu sein, aber Die HAVING-Klausel kann entweder eine Spalte oder einen Alias ​​verwenden.

Dies liegt daran, dass WHERE-Klausel Daten vor Auswahl filtert, aber HAVING-Klausel filtert Daten nach Auswahl.

Also setzen Sie die Bedingungen in WHERE-Klausel effizienter, wenn Sie viele viele Zeilen in einer Tabelle haben.

Versuchen Sie erklären den entscheidenden Unterschied 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 sehen entweder WHERE oder HAVING Verwendungen Index, aber die Zeilen unterschiedlich sind.

+22

Ich weiß, dass Sie EXPLAIN erwähnt! – paiego

+0

Da die HAVING-Klausel Daten nach Auswahl filtert, ist die WHERE-Klausel effektiver. Wenn das wahr ist, wann müssen wir dann HAVING anstelle von WHERE verwenden? – grep

+5

@grep Wenn Sie Daten nach Auswahl filtern müssen, benötigen Sie die HAVING-Klausel, normalerweise verwenden wir sie mit GROUP BY-Klausel, zB: 'SELECT-Wert, COUNT (*) Häufigkeit FROM Tabelle GROUP BY-Wert mit Häufigkeit> 10' – Fishdrowned

4

Diese 2 werden gleich wie die ersten sein, da beide verwendet werden, um über eine Bedingung zum Filtern von Daten zu sagen. Obwohl wir "Haben" anstelle von "Wo" verwenden können, gibt es Fälle, in denen wir nicht "Wo" statt "Haben" verwenden können. Dies liegt daran, dass in einer Select-Abfrage "where" Daten vor "select" filtert, während "filter" nach "select" gefiltert wird. Wenn wir also Alias-Namen verwenden, die sich nicht in der Datenbank befinden, kann "where" sie nicht identifizieren, sondern "haben".

Beispiel: Lassen Sie die Tabelle Student student_id, Name, Geburtstag, Adresse enthalten.Assume 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.*/ 
+0

Dieses Beispiel aus dem wirklichen Leben verdeutlicht den Unterschied zwischen 'WHERE' und' HAVING'. –

1

Nachdem nur mit Aggregation verwendet, aber wo mit nicht-Aggregation Aussagen Wenn Sie in dem Wort, um es vor der Aggregation setzen (Gruppe)

0
  • A WHERE Klausel verwendet wird, ist Filter Datensätze aus ein Ergebnis. Der Filter tritt auf, bevor Gruppierungen vorgenommen werden.
  • Eine HAVING Klausel wird verwendet, um Werte aus einer Gruppe zu filtern. Bevor wir weiter gehen gehen wir das Format einer SQL-Anweisung überprüfen. Es ist

    SELECT SalesOrderID, SUM (Einzelpreis * OrderQty) AS Totalprice VON Sales.SalesOrderDetail WHERE Linetotal> 100 GROUP BY SalesOrderID , DIE SUMME (Einzelpreis * OrderQty)> 10000

Key Punkt, der auch der Hauptunterschied zwischen der Klausel WHERE und HAVING in SQL ist, dass die in der WHERE-Klausel angegebene Bedingung beim Abrufen von Daten (Zeilen) aus der Tabelle verwendet wird, und Daten, die die Bedingung nicht bestehen, werden nicht in die Ergebnismenge abgerufen Andererseits wird die HAVING-Klausel später zum Filtern von zusammengefassten Daten oder verwendet gruppierte Daten. Kurz

In wenn beid WHERE und MIT Klausel in einer SELECT-Abfrage mit Aggregatfunktion oder GROUP BY-Klausel verwendet wird, wird es ausgeführt werden, bevor HAVING-Klausel.

0

WHERE Filter, bevor die Daten gruppiert und MIT Filter nach Daten gruppiert sind. Dies ist eine wichtige Unterscheidung; Zeilen, die sind, werden durch eine WHERE-Klausel eliminiert, die nicht in der Gruppe enthalten ist. Diese könnte die berechneten Werte ändern, die wiederum beeinflussen könnten, welche Gruppen auf der Grundlage der Verwendung dieser Werte in dem Abschnitt HAVING gefiltert werden.

Auszug aus: Forta, Ben. "Sams Teach Yourself SQL in 10 Minuten (4. Edition) (Sams Teach Yourself ...).".