SQL-mając vs. gdzie

Mam następujące dwie tabele:

1. Lecturers (LectID, Fname, Lname, degree).
2. Lecturers_Specialization (LectID, Expertise).
Chcę znaleźć wykładowcę z największą specjalizacją. Kiedy próbuję 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 jak spróbuję to 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.
Author: Kaushal28, 2012-02-12

8 answers

WHERE klauzula wprowadza warunek na poszczególnych wierszach; HAVING klauzula wprowadza warunek dla agregacji , tj. wyników selekcji, w których pojedynczy wynik, taki jak count, average, min, max lub sum, został wytworzony z wielu wierszy. Twoje zapytanie wywołuje drugi rodzaj warunku (tj. warunek na agregacji) stąd HAVING działa poprawnie.

Z reguły należy stosować WHERE Przed GROUP BY i HAVING Po GROUP BY. Jest to raczej prymitywne zasada, ale jest przydatna w ponad 90% przypadków.

Gdy już nad tym pracujesz, możesz napisać ponownie zapytanie używając ANSI w wersji join:

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)

Wyeliminowałoby to WHERE, który został użyty jako warunekTheta join .

 378
Author: Sergey Kalinichenko,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-26 20:35:40

HAVING działa na agregatach. Ponieważ COUNT jest funkcją zbiorczą, nie można jej użyć w klauzuli WHERE.

Oto kilka odczytów z MSDN na temat funkcji agregujących.

 42
Author: Daniel Mann,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-02-12 22:19:10

Najpierw powinniśmy poznać kolejność wykonania klauzul tj. FROM > WHERE > GROUP BY > HAVING > DISTINCT > SELECT > ORDER BY. Ponieważ Gdzie klauzula jest wykonywana przed GROUP BY Klauzula, rekordy nie mogą być filtrowane przez zastosowanie Gdzie do grupy przez zastosowanych rekordów.

"HAVING jest takie samo jak klauzula WHERE, ale jest stosowane na zbiorczych rekordów".

Najpierw Gdzie klauzula pobiera rekordy na podstawie warunku następnie klauzula GROUP BY grupuje je odpowiednio, a klauzula HAVING pobiera rekordy grupy na podstawie warunku having.

 38
Author: Pardhu,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-27 13:41:52
  1. Klauzula WHERE może być używana z instrukcjami SELECT, INSERT i UPDATE, podczas gdy HAVING może być używana tylko z instrukcją SELECT.

  2. Gdzie filtruje wiersze przed agregacją( GROUP BY), natomiast po agregacji wykonuje się filtrowanie grup.

  3. Funkcja agregująca nie może być użyta w klauzuli WHERE, chyba że znajduje się w zapytaniu podrzędnym zawartym w klauzuli HAVING, natomiast funkcje agregujące mogą być użyte w klauzuli HAVING klauzula.

Źródło

 20
Author: Venkata Krishna Reddy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-07-13 15:22:01

Nie widziałem przykładu obu w jednym zapytaniu. Więc ten przykład może pomóc.

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

To filtruje tabelę najpierw według identyfikatora firmy, następnie grupuje ją (według kraju i miasta) i dodatkowo filtruje ją do tylko agregacji miast Meksyku. Identyfikator companyId nie był potrzebny w agregacji, ale byliśmy w stanie użyć WHERE, aby odfiltrować tylko wiersze, które chcieliśmy przed użyciem GROUP BY.

 12
Author: Nhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-27 23:15:07

Nie możesz używać klauzuli where z funkcjami agregującymi, ponieważ where fetch rekordów na podstawie warunku, przechodzi do rekordu tabeli po rekordzie, a następnie do rekordu fetch na podstawie warunku, który mamy give. Więc tym razem nie możemy gdzie klauzula. Podczas gdy klauzula działa na resultSet, który ostatecznie otrzymujemy po uruchomieniu zapytania.

Przykładowe zapytanie:

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

To zapisze resultSet w pamięci tymczasowej, a klauzula wykona swoją pracę. Więc możemy łatwo użyj funkcji agregujących tutaj.

 9
Author: Akash5288,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-03-27 13:32:10

1. Możemy użyć funkcji agregującej z klauzulą HAVING not by WHERE np. min, max, avg.

2. Gdzie klauzula eliminuje rekord krotka przez krotkę Posiadanie klauzuli eliminuje całą grupę ze zbioru group

Głównie HAVING jest używany, gdy masz grupy danych i WHERE jest używany, gdy masz dane w wierszach.

 4
Author: Mihir Trivedi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-06-29 15:51:16

WHERE klauzula jest używana do eliminowania krotek w relacji, a klauzula HAVING jest używana do eliminowania grup w relacji.

HAVING klauzula służy do funkcji agregujących, takich jak MIN,MAX,COUNT,SUM .Ale zawsze używaj klauzuli GROUP BY przed klauzulą HAVING, aby zminimalizować błąd.

 0
Author: Doddi girish,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-07-22 13:25:05