哪里与拥有 SQL

Where vs Having SQL

我是 SQL 的新手,我想知道 Where 子句和 Having 子句之间的区别。对我来说,它有点相同,都用于过滤记录。 谢谢你给我信息。

WHERE 用于在 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

供您参考,除了 SELECT 查询外,您还可以将 WHERE 子句与 UPDATEDELETE[=32= 一起使用] 子句,但 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 子句用于根据指定的条件过滤组。