SQL - имея VS где - PullRequest
       64

SQL - имея VS где

174 голосов
/ 13 февраля 2012

У меня есть следующие две таблицы:

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

Я хочу найти лектора с наибольшей специализацией.Когда я пытаюсь это, он не работает:

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

Но когда я пытаюсь это, он работает:

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

В чем причина?Благодаря.

Ответы [ 7 ]

312 голосов
/ 13 февраля 2012

WHERE предложение вводит условие для отдельных строк ; Предложение HAVING вводит условие для агрегатов , т. Е. Результатов выбора, когда один результат, такой как число, среднее, минимальное, максимальное или суммарное, был получен из нескольких строк , Ваш запрос требует условия второго типа (то есть условия агрегации), следовательно, HAVING работает правильно.

Как правило, используйте WHERE перед GROUP BY и HAVING после GROUP BY. Это довольно примитивное правило, но оно полезно в более чем 90% случаев.

Пока вы это делаете, вы можете переписать запрос, используя версию объединения ANSI:

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)

Это исключит WHERE, которое использовалось как условие тета-соединения .

35 голосов
/ 13 февраля 2012

HAVING работает на агрегаты.Поскольку COUNT является агрегатной функцией, вы не можете использовать ее в предложении WHERE.

Вот некоторое чтение из MSDN для агрегатных функций.

21 голосов
/ 27 марта 2017

Сначала мы должны знать порядок выполнения Условий, т. Е. ОТ> ГДЕ> GROUP BY> HAVING> DISTINCT> SELECT> ORDER BY. Так как WHERE Предложение выполняется до GROUP BY Условие: записи не могут быть отфильтрованы путем применения WHERE к GROUP BY примененным записям.

"HAVING аналогичен WHEREно применяется к сгруппированным записям ".

сначала предложение WHERE извлекает записи на основе условия, затем предложение GROUP BY группирует их соответственно изатем предложение HAVING извлекает групповые записи на основе условия наличия.

13 голосов
/ 28 мая 2016
  1. Предложение WHERE может использоваться с операторами SELECT, INSERT и UPDATE, тогда как HAVING может использоваться только с оператором SELECT.

  2. WHERE фильтрует строки перед агрегированием(GROUP BY), тогда как группы фильтров HAVING после агрегирования выполняются.

  3. Агрегатная функция не может использоваться в предложении WHERE, если она не входит в подзапрос, содержащийся в предложении HAVING, тогда как агрегатные функциииспользуется в предложении HAVING.

Источник

9 голосов
/ 28 июля 2016

Не видел пример обоих в одном запросе.Таким образом, этот пример может помочь.

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

Это фильтрует таблицу сначала по companyId, затем группирует ее (по стране и городу) и дополнительно фильтрует ее только по городским агрегатам Мексики.Идентификатор компании не был необходим в агрегации, но мы смогли использовать WHERE для фильтрации только тех строк, которые нам нужны, прежде чем использовать GROUP BY.

8 голосов
/ 10 декабря 2013

Вы не можете использовать предложение where с агрегатными функциями, потому что, когда выборка производится на основе условия, она переходит в запись таблицы по записи, а затем выбирает запись на основе условия, которое мы дали.Так что время мы не можем, где оговорка.В то время как наличие условия работает с набором результатов, который мы наконец получаем после выполнения запроса.

Пример запроса:

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

Это сохранит результирующий набор во временной памяти, а затем с выполнением предложения, имеющего предложение.Таким образом, мы можем легко использовать агрегатные функции здесь.

4 голосов
/ 29 июня 2016

1.Мы можем использовать агрегатную функцию с предложением HAVING не с предложением WHERE, например, min, max, avg.

2.Предложение WHERE исключает кортеж записи по кортежу Предложение HAVING исключает всю группу из коллекции группы

В основном HAVING используется, когда у вас есть группы данных, и WHERE используется, когда у вас есть данные в строках.

...