SQL - 有VS在哪里

时间:2012-02-12 22:17:02

标签: sql where having

我有以下两个表:

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

是什么原因?感谢。

8 个答案:

答案 0 :(得分:307)

WHERE子句在各行上引入了一个条件; HAVING子句引入聚合的条件,即选择结果,其中单个结果(例如计数,平均值,最小值,最大值或总和)已从倍<生成< / em>行。您的查询调用第二种条件(即聚合条件),因此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)

这将消除用作 theta连接条件WHERE

答案 1 :(得分:34)

HAVING对聚合进行操作。由于COUNT是一个聚合函数,因此不能在WHERE子句中使用它。

Here's从MSDN读取一些关于聚合函数的内容。

答案 2 :(得分:19)

首先我们应该知道条款的执行顺序,即 FROM&gt;在哪里&gt; GROUP BY&gt; HAVING&gt; DISTINCT&gt;选择&gt;订购。 由于 WHERE 条款在 GROUP BY 条款之前执行,因此无法通过将 WHERE 应用于 GROUP BY 来过滤记录记录。

“HAVING与WHERE子句相同,但应用于分组记录”。

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

答案 3 :(得分:13)

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

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

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

  4. Source

答案 4 :(得分:8)

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

示例查询:

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

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

答案 5 :(得分:8)

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

  /**
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过滤表格,然后将其分组(按国家/地区和城市),并将其过滤到墨西哥的城市聚合。聚合中不需要companyId,但我们能够在使用GROUP BY之前使用WHERE过滤掉我们想要的行。

答案 6 :(得分:4)

1。 我们可以使用聚合函数和HAVING子句而不是WHERE子句,例如最小值,最大值,平均值

2。 WHERE子句通过元组消除了记录元组 HAVING子句从组

中删除整个组

当您拥有数据组时,通常使用HAVING,当您有数据行时使用WHERE。

答案 7 :(得分:0)

WHERE子句用于消除关系中的元组,而HAVING子句用于消除关系中的组。

HAVING子句用于聚合函数,例如 MINMAXCOUNTSUM。但是请始终在GROUP BY子句之前使用HAVING子句以最大程度地减少错误。