SQL - 有VS在哪里

Ada*_* Sh 184 sql where having

我有以下两个表:

1. Lecturers (LectID, Fname, Lname, degree).
2. Lecturers_Specialization (LectID, Expertise).
Run Code Online (Sandbox Code Playgroud)

我想找到专业化程度最高的讲师.当我尝试这个时,它不起作用:

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);
Run Code Online (Sandbox Code Playgroud)

但是当我尝试这个时,它有效:

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); 
Run Code Online (Sandbox Code Playgroud)

是什么原因?谢谢.

das*_*ght 328

WHERE子句引入了各行的条件; HAVING子句引入聚合条件,即选择结果,其中从行生成单个结果,例如计数,平均值,最小值,最大值或总和.您的查询调用第二种条件(即聚合条件)因此HAVING可以正常工作.

作为一个经验法则,使用WHERE之前GROUP BYHAVING之后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)
Run Code Online (Sandbox Code Playgroud)

这将消除WHERE用作theta连接条件的情况.

  • 为什么每个人都通过聚合来解释“HAVING”?这很令人困惑,而且不是完整的答案。`HAVING` 稍后在结果集上运行。我们不需要聚合来需要“HAVING”。例如,有时我们计算列值,然后需要“HAVING”将我们的结果集限制为某些值。 (4认同)
  • @SergeyKalinichenko 好吧,很公平。然而,即使大多数教程都是这样解释“HAVING”与“WHERE”的:“如果有聚合,请使用“HAVING””。我记得由于这些糟糕的解释,我在理解“HAVING”实际上是如何工作时遇到了(双关语无意的)问题。 (3认同)

Dan*_*ann 37

HAVING在聚合上运作.由于COUNT是聚合函数,因此不能在WHERE子句中使用它.

以下是 MSDN对聚合函数一些解读.


Par*_*dhu 23

首先我们应该知道子句的执行顺序,即 FROM> WHERE> GROUP BY> HAVING> DISTINCT> SELECT> ORDER BY. 由于WHERE子句被执行之前GROUP BY子句中的记录无法通过应用过滤WHEREGROUP BY应用的记录.

"HAVING与WHERE子句相同,但应用于分组记录".

首先,WHERE子句根据条件获取记录,然后GROUP BY子句相应地对它们进行分组,然后HAVING子句根据条件获取组记录.

  • @MSIS 即使查询优化器更改顺序,结果也应该与遵循此顺序相同。这是一个逻辑顺序。 (4认同)

Ven*_*ddy 15

  1. WHERE子句可以与SELECT,INSERT和UPDATE语句一起使用,而HAVING只能与SELECT语句一起使用.

  2. WHERE在聚合之前过滤行(GROUP BY),而在聚合之后执行HAVING过滤器组.

  3. 聚合函数不能在WHERE子句中使用,除非它在HAVING子句中包含的子查询中,而聚合函数可以在HAVING子句中使用.

资源


Nha*_*han 11

在一个查询中没有看到两者的示例.所以这个例子可能有帮助.

  /**
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
Run Code Online (Sandbox Code Playgroud)

这将首先由companyId过滤表格,然后将其分组(按国家/地区和城市),并将其过滤到墨西哥的城市聚合.聚合中不需要companyId,但我们能够在使用GROUP BY之前使用WHERE过滤掉我们想要的行.


Aka*_*288 9

你不能使用带有聚合函数的where子句,因为在条件的基础上获取记录,它按记录进入表记录,然后根据我们给出的条件获取记录.那么那个时候我们就不能在哪里了.虽然having子句适用于我们在运行查询后最终得到的resultSet.

示例查询:

select empName, sum(Bonus) 
from employees 
order by empName 
having sum(Bonus) > 5000;
Run Code Online (Sandbox Code Playgroud)

这会将resultSet存储在临时内存中,然后having子句将执行其工作.所以我们可以在这里轻松使用聚合函数.

  • 我认为没有GROUP BY子句就不能使用HAVING子句。HAVING子句的位置-SELECT-> FROM-> WHERE-> GROUP BY-> HAVING-> ORDER BY (2认同)