当涉及到在SQL查询中过滤记录时,有两个主要选项,要么使用WHERE子句,要么使用HAVING子句。
虽然WHERE和HAVING都用于过滤行,但WHERE子句中的条件是在数据分组之前应用的,而HAVING子句中的条件是在分组之后应用的。
它们之间的主要区别是,如果你想在对记录进行分组之前过滤数据,也就是在使用GROUP BY子句对记录进行分组之前,你可以使用WHERE子句;而当你想过滤分组时,使用HAVING子句。
这种区分是由大多数流行数据库(如MySQL、Microsoft SQL Server、Oracle和PostgreSQL)的查询引擎所做出的。
例如,
只会显示Price大于12的数据,这里我们使用了WHERE子句,因为没有进行分组。
如果我们需要按物流公司名字以及订单数量,我们可以同时使用GROUP BY和HAVING子句。
还可以在一个查询中同时使用WHERE和HAVING子句,在这种情况下,WHERE子句将在分组之前进行过滤,而HAVING子句将在分组之后进行过滤,如下例所示:
在SQL中,WHERE子句与HAVING子句的区别主要体现在以下几个方面:
-
过滤时机:
WHERE
子句用于在数据分组之前进行过滤。也就是说,当执行GROUP BY
语句之前,WHERE
会先筛选出符合条件的行。HAVING
子句则用于在数据分组之后进行过滤。它针对的是分组后的结果集,而不是单个的记录。
-
使用场景:
- 当你需要对原始数据进行筛选,而不考虑分组的情况时,使用
WHERE
子句。 - 当你需要基于分组的聚合结果进行筛选时,使用
HAVING
子句。
- 当你需要对原始数据进行筛选,而不考虑分组的情况时,使用
-
与聚合函数的配合:
WHERE
子句不能直接与聚合函数(如COUNT()
,SUM()
,AVG()
等)一起使用,因为它处理的是单个记录。HAVING
子句可以与聚合函数一起使用,因为它处理的是分组后的汇总数据。
-
性能考虑:
- 由于
WHERE
在分组前进行过滤,因此它可以减少进入分组操作的数据量,从而有可能提高查询性能。 HAVING
在分组后进行过滤,所以它处理的是已经分组的数据,这可能会导致更多的数据处理,从而影响性能。但在某些情况下,使用HAVING
是必要的,特别是当需要基于分组结果进行筛选时。
- 由于
总之,WHERE
和 HAVING
在SQL查询中各自扮演了不同的角色,根据具体的需求和场景来选择使用哪一个。