webentwicklung-frage-antwort-db.com.de

SQL - mit VS wo

Ich habe die folgenden zwei Tabellen:

1. Lecturers (LectID, Fname, Lname, degree).
2. Lecturers_Specialization (LectID, Expertise).

Ich möchte den Dozenten mit der höchsten Spezialisierung finden. Wenn ich das versuche, funktioniert es nicht:

SELECT
  L.LectID, 
  Fname, 
  Lname 
FROM Lecturers L, 
     Lecturers_Specialization S
WHERE L.LectID = S.LectID
AND COUNT(S.Expertise) >= ALL (SELECT
  COUNT(Expertise)
FROM Lecturers_Specialization
GROUP BY LectID);

Aber wenn ich das versuche, funktioniert es:

SELECT
  L.LectID,
  Fname,
  Lname 
FROM Lecturers L,
     Lecturers_Specialization S
WHERE L.LectID = S.LectID
GROUP BY L.LectID,
         Fname,
         Lname 
HAVING COUNT(S.Expertise) >= ALL (SELECT
  COUNT(Expertise)
FROM Lecturers_Specialization
GROUP BY LectID); 

Was ist der Grund? Vielen Dank.

176
Adam Sh

Die WHERE -Klausel führt eine Bedingung für einzelne Zeilen ein. Die HAVING -Klausel führt eine Bedingung für Aggregationen ein, dh Ergebnisse der Auswahl, bei denen ein einzelnes Ergebnis wie Anzahl, Durchschnitt, Minimum, Maximum oder Summe aus mehrere Zeilen. Ihre Abfrage erfordert eine zweite Art von Bedingung (d. H. Eine Bedingung für eine Aggregation), sodass HAVING ordnungsgemäß funktioniert.

Als Faustregel verwenden Sie WHERE vor GROUP BY und HAVING nach GROUP BY. Es ist eine eher primitive Regel, aber in mehr als 90% der Fälle nützlich.

Wenn Sie schon dabei sind, können Sie Ihre Abfrage mithilfe der ANSI-Version des Joins neu schreiben:

SELECT  L.LectID, Fname, Lname
FROM Lecturers L
JOIN Lecturers_Specialization S ON L.LectID=S.LectID
GROUP BY L.LectID, Fname, Lname
HAVING COUNT(S.Expertise)>=ALL
(SELECT COUNT(Expertise) FROM Lecturers_Specialization GROUP BY LectID)

Dies würde WHERE eliminieren, das als Theta-Join-Bedingung verwendet wurde.

318
dasblinkenlight

HAVING bearbeitet Aggregate. Da COUNT eine Aggregatfunktion ist, können Sie sie nicht in einer WHERE -Klausel verwenden.

hier ist Lesen von MSDN zu Aggregatfunktionen.

35
Daniel Mann

Zunächst sollten wir die Ausführungsreihenfolge der Klauseln kennen, dh FROM> WHERE> GROUP BY> HAVING> DISTINCT> SELECT> ORDER BY. Since WHERE Die Klausel wird ausgeführt, bevor GROUP BY Die Datensätze können nicht gefiltert werden, indem WOBEI auf ein GROUP BY) angewendet wird angewandte Datensätze.

"HAVING ist mit der WHERE-Klausel identisch, wird jedoch auf gruppierte Datensätze angewendet".

zuerst die WOBEI -Klausel die Datensätze basierend auf der Bedingung abruft, dann die GROUP BY -Klausel sie entsprechend gruppiert und dann die HAVING - Klausel ruft die Gruppendatensätze basierend auf der having-Bedingung ab.

21
Pardhu
  1. Die WHERE-Klausel kann mit SELECT-, INSERT- und UPDATE-Anweisungen verwendet werden, während HAVING nur mit SELECT-Anweisungen verwendet werden kann.

  2. WHERE filtert Zeilen vor der Aggregation (GROUP BY), HAVING filtert Gruppen nach der Aggregation.

  3. Aggregatfunktionen können nicht in der WHERE-Klausel verwendet werden, es sei denn, sie befinden sich in einer Unterabfrage in der HAVING-Klausel, während Aggregatfunktionen in der HAVING-Klausel verwendet werden können.

Quelle

13

Ich habe kein Beispiel für beides in einer Abfrage gesehen. Also könnte dieses Beispiel helfen.

  /**
INTERNATIONAL_ORDERS - table of orders by company by location by day
companyId, country, city, total, date
**/

SELECT country, city, sum(total) totalCityOrders 
FROM INTERNATIONAL_ORDERS with (nolock)
WHERE companyId = 884501253109
GROUP BY country, city
HAVING country = 'MX'
ORDER BY sum(total) DESC

Dies filtert die Tabelle zuerst nach der Unternehmens-ID, gruppiert sie dann (nach Land und Stadt) und filtert sie zusätzlich nach Stadtaggregationen in Mexiko. Die companyId wurde in der Aggregation nicht benötigt, aber wir konnten WHERE verwenden, um nur die gewünschten Zeilen herauszufiltern, bevor GROUP BY verwendet wurde.

10
Nhan

Sie können die where-Klausel nicht mit Aggregatfunktionen verwenden, da beim Abrufen von Datensätzen auf der Grundlage von Bedingungen die Tabelle Datensatz für Datensatz abgerufen wird und dann der Datensatz auf der Grundlage der von uns angegebenen Bedingungen abgerufen wird. Also diesmal können wir nicht wo Klausel. While having-Klausel arbeitet mit dem resultSet, das wir schließlich erhalten, nachdem wir eine Abfrage ausgeführt haben.

Beispielabfrage:

select empName, sum(Bonus) 
from employees 
order by empName 
having sum(Bonus) > 5000;

Dadurch wird das resultSet in einem temporären Speicher abgelegt, und mit der having-Klausel wird die Arbeit ausgeführt. Daher können wir hier leicht Aggregatfunktionen verwenden.

8
Akash5288

1. Wir können die Aggregatfunktion mit der HAVING-Klausel verwenden, nicht mit der WHERE-Klausel, z. min, max, durchschn.

2. WHERE-Klausel beseitigt den Datensatz Tuple by Tuple HAVING-Klausel beseitigt die gesamte Gruppe aus der Gruppensammlung

HAVING wird meistens verwendet, wenn Sie Datengruppen haben, und WHERE, wenn Sie Daten in Zeilen haben.

4
Mihir Trivedi