我是SQL的新手,我想知道Where子句和Haveing子句有什么区别。对我来说,这有点相同,并且都用于过滤记录。 谢谢你给我信息。
答案 0 :(得分:3)
WHERE用于在GROUP BY作用于记录之前(或在没有group by的查询中)过滤记录
HAVING用于在GROUP BY作用于行之后过滤它们。您只能在HAVING子句中指定了已分组的列,或者它们是聚合的一部分(意味着它们被传递给SUM(column),AVG(column),COUNT(column)等函数)>
帐户员工的加薪幅度超过一次:
--yes
SELECT emp_name
FROM pay_rise_log
WHERE dept = 'accounts'
GROUP BY emp_name
HAVING count(*) > 1
--yes - equivalent if HAVING wasn't a thing
SELECT emp_name
FROM (
--do this first, count the records
SELECT emp_name, COUNT(*) as ct
FROM pay_rise_log
WHERE dept = 'accounts'
GROUP BY emp_name
) a
WHERE a.ct > 1 --and now filter to more than one pay rise
--no, you can't use a count(*) (done during a group by) before the group by is performed
SELECT emp_name
FROM pay_rise_log
WHERE dept = 'accounts' AND count(*) > 1
GROUP BY emp_name
--no
SELECT emp_name
FROM pay_rise_log
WHERE dept = 'accounts'
GROUP BY emp_name
HAVING count(*) > 1 AND gender = 'male' --no, the gender column was not grouped and is not presented inside an aggregate function
--works, but is unusual. gender should be in the where clause
SELECT emp_name
FROM pay_rise_log
WHERE dept = 'accounts'
GROUP BY emp_name, gender
HAVING count(*) > 1 AND gender = 'male'
--works, but gender should be part of the WHERE clause to avoid needlessly counting females
--also has a potential bug if genders alphabetically after 'male' are present
--though it would count people who have been male even if they aren't currently, which may be a bonus?!
SELECT emp_name
FROM pay_rise_log
WHERE dept = 'accounts'
GROUP BY emp_name
HAVING count(*) > 1 AND MAX(gender) = 'male'
从学习的角度来看,MySQL有点痛苦,因为在某些配置中,您可以省略GROUP BY,而它会为您隐式执行,因此您可能不会意识到正在执行GROUP BY。
为回应您的评论,您可以在分组依据之前使用WHERE;您可以使用它来选择要分组的记录。如果有100,000名员工,而帐户部门中只有100名员工,那么对所有员工进行分组和计数就没有意义,而只是将99%的数据丢掉了:
--yes
SELECT emp_name
FROM pay_rise_log
WHERE dept = 'accounts' --pick 100 employees
GROUP BY emp_name
HAVING count(*) > 1 --pick only those with 2 or more pay rises
--no (and potentially wrong too)
SELECT emp_name
FROM pay_rise_log --pick 100,000 employees
GROUP BY emp_name
HAVING count(*) > 1 and MAX(dept) = 'accounts' --pick only accounts staff who had more than 1 pay rise
答案 1 :(得分:-1)
为供参考,除SELECT
查询外,您可以将WHERE
子句与 UPDATE 和 DELETE 子句一起使用,但HAVING
子句只能与SELECT
查询一起使用。示例:
update CUSTOMER set CUST_NAME="Johnny" WHERE CUST_ID=1; //This line of code worked
update CUSTOMER set CUST_NAME="Johnny" HAVING CUST_ID=1; //Incorrect Syntax
WHERE子句用于过滤行,它适用于每一行,而HAVING子句用于过滤SQL中的行组。
虽然WHERE
和HAVING
子句可以在具有聚合功能的 SELECT 查询中一起使用。
SELECT CUST_ID, CUST_NAME, CUST_GENDER
FROM CUSTOMER
WHERE CUST_GENDER='MALE'
GROUP BY CUST_ID
HAVING CUST_ID=8;
在这种情况下,WHERE
子句将首先应用于单个行,并且仅包含通过条件的行才能创建组。创建组后,将使用HAVING子句根据指定的条件过滤组。