Mam następujące dwie tabele:
1. Lecturers (LectID, Fname, Lname, degree).
2. Lecturers_Specialization (LectID, Expertise).
Chcę znaleźć wykładowcę o największej specjalizacji. Kiedy próbuję tego, to nie działa:
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);
Ale gdy spróbuję, działa:
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);
Jaki jest powód? Dzięki.
Odpowiedzi:
WHERE
klauzula wprowadza warunek w poszczególnych wierszach ;HAVING
klauzula wprowadza warunek dotyczący agregacji , tj. wyników selekcji, w których pojedynczy wynik, taki jak liczba, średnia, min, maks lub suma, został wygenerowany z wielu wierszy. Twoje zapytanie wymaga drugiego rodzaju warunku (tj. Warunku agregacji), a zatemHAVING
działa poprawnie.Z reguły należy stosować
WHERE
przedGROUP BY
iHAVING
poGROUP BY
. Jest to raczej prymitywna reguła, ale jest przydatna w ponad 90% przypadków.W tym momencie możesz ponownie napisać zapytanie, używając wersji złączenia ANSI:
To wyeliminowałoby to,
WHERE
co zostało użyte jako warunek połączenia theta .źródło
HAVING
działa na agregatach. PonieważCOUNT
jest to funkcja agregująca, nie można jej użyć wWHERE
klauzuli.Oto kilka lektur z MSDN na temat funkcji agregujących.
źródło
Najpierw powinniśmy znać kolejność wykonywania Klauzul, tj. Z> GDZIE> GRUPUJ WEDŁUG> POSIADAJĄ> WYRÓŻNIJ> WYBIERZ> ZAMÓW WG. Ponieważ klauzula WHERE jest wykonywana przed klauzulą GROUP BY, rekordy nie mogą być filtrowane poprzez zastosowanie WHERE do zastosowanych rekordów GROUP BY .
„HAVING jest taki sam jak klauzula WHERE, ale jest stosowany do zgrupowanych rekordów”.
najpierw klauzula WHERE pobiera rekordy na podstawie warunku, następnie klauzula GROUP BY odpowiednio je grupuje, a następnie klauzula HAVING pobiera rekordy grupy na podstawie warunku posiadania.
źródło
Klauzula WHERE może być używana z instrukcjami SELECT, INSERT i UPDATE, natomiast HAVING może być używana tylko z instrukcją SELECT.
GDZIE filtruje wiersze przed agregacją (GROUP BY), natomiast HAVING filtruje grupy po agregacji.
Funkcji agregującej nie można używać w klauzuli WHERE, chyba że znajduje się ona w podzapytaniu zawartym w klauzuli HAVING, natomiast funkcji agregujących można używać w klauzuli HAVING.
Źródło
źródło
Nie widziałem przykładu obu w jednym zapytaniu. Ten przykład może pomóc.
To najpierw filtruje tabelę według nazwy firmy, a następnie grupuje ją (według kraju i miasta), a dodatkowo filtruje do tylko agregacji miast w Meksyku. Firma nie była potrzebna w agregacji, ale mogliśmy użyć GDZIE, aby odfiltrować tylko wiersze, które chcieliśmy przed użyciem GROUP BY.
źródło
Nie można użyć klauzuli where z funkcjami agregującymi, ponieważ skąd pobierają rekordy na podstawie warunku, przechodzą do tabeli rekord po rekordzie, a następnie pobierają rekord na podstawie podanego przez nas warunku. Więc tym razem nie możemy dokąd klauzula. Posiadanie klauzuli działa na zestawie wyników, który w końcu otrzymujemy po uruchomieniu zapytania.
Przykładowe zapytanie:
Spowoduje to zapisanie scoreSet w pamięci tymczasowej, a następnie posiadanie klauzuli wykona swoją pracę. Dzięki temu możemy łatwo korzystać z funkcji agregujących.
źródło
1. Możemy użyć funkcji agregującej z klauzulą HAVING, a nie klauzulą WHERE, np. Min, max, avg.
2. GDZIE klauzula eliminuje rekord krotki przez krotkę klauzula HAVING eliminuje całą grupę z kolekcji grupy
Najczęściej HAVING jest używany, gdy masz grupy danych, a GDZIE jest używany, gdy masz dane w wierszach.
źródło