我有以下两张表:
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);
原因是什么?谢谢。
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)
这将消除用作
theta 连接条件的
WHERE
。
首先我们应该知道条款的执行顺序,即 来自 > 何处 > 分组依据 > 具有 > 不同 > 选择 > 排序依据。 由于 WHERE 子句在 GROUP BY 子句之前执行,因此无法通过将 WHERE 应用于 GROUP BY 应用的记录来过滤记录。
“HAVING 与 WHERE 子句相同,但应用于分组记录”。
首先,WHERE子句根据条件获取记录,然后GROUP BY子句对它们进行相应的分组,然后HAVING子句根据having条件获取组记录。
WHERE
子句可与 SELECT
、INSERT
和 UPDATE
语句一起使用,而 HAVING
只能与 SELECT
语句一起使用。
WHERE
在聚合之前过滤行 (GROUP BY
),而 HAVING
在执行聚合之后过滤组。
聚合函数不能在
WHERE
子句中使用,除非它位于HAVING
子句中包含的子查询中,而聚合函数可以在HAVING
子句中使用。
在一个查询中没有看到两者的示例。所以这个例子可能会有所帮助。
/**
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 过滤出我们想要的行。
不能将where子句与聚合函数一起使用,因为where根据条件获取记录,它会逐条记录地进入表记录,然后根据我们给出的条件获取记录。所以到时候我们就可以不用where子句了。而having子句适用于我们在运行查询后最终得到的结果集。
查询示例:
select empName, sum(Bonus)
from employees
order by empName
having sum(Bonus) > 5000;
这会将结果集存储在临时内存中,然后having子句将执行其工作。所以我们可以在这里轻松使用聚合函数。
1. 我们可以将聚合函数与 HAVING 子句一起使用,而不是与 WHERE 子句一起使用,例如最小值、最大值、平均值。
2. WHERE 子句逐元组消除记录元组 HAVING 子句从组集合中消除整个组
当您有数据组时,通常使用 HAVING;当您有行数据时,通常使用 WHERE。
WHERE
子句用于消除关系中的元组,HAVING
子句用于消除关系中的组。
HAVING
子句用于聚合函数,例如
MIN
,MAX
,COUNT
,SUM
。但始终在 GROUP BY
子句之前使用 HAVING
子句以尽量减少错误。
WHERE
和HAVING
都用于过滤数据。
如果是 WHERE
语句,数据过滤会在您提取数据进行操作之前进行。
SELECT name, age
FROM employees
WHERE age > 30;
此处
WHERE
子句在执行 SELECT
操作之前过滤行。
SELECT department, avg(age) avg_age
FROM employees
GROUP BY department
HAVING avg_age> 35;
HAVING
在执行 SELECT
操作后过滤数据。这里首先完成计算(聚合)操作,然后使用 HAVING
子句对结果应用过滤器。
哪里
拥有
如果查询中不使用 GROUP BY,HAVING 与 WHERE 效果相同