哪里与拥有SQL

时间:2018-09-12 09:47:12

标签: mysql where-clause having-clause

我是SQL的新手,我想知道Where子句和Haveing子句有什么区别。对我来说,这有点相同,并且都用于过滤记录。 谢谢你给我信息。

2 个答案:

答案 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中的行组

虽然WHEREHAVING子句可以在具有聚合功能的 SELECT 查询中一起使用。

SELECT CUST_ID, CUST_NAME, CUST_GENDER
FROM CUSTOMER
WHERE CUST_GENDER='MALE'
GROUP BY CUST_ID
HAVING CUST_ID=8;

在这种情况下,WHERE子句将首先应用于单个行,并且仅包含通过条件的行才能创建组。创建组后,将使用HAVING子句根据指定的条件过滤组。