- WHERE用于过滤行级数据,而HAVING用于过滤分组级别的数据。
- WHERE在数据分组之前应用,而HAVING在数据分组之后应用。
- WHERE可以使用聚合函数,但不能在WHERE子句中使用聚合函数的结果进行过滤,而HAVING可以使用聚合函数并且可以使用聚合函数的结果进行过滤。
具体来说,WHERE子句是在从表中检索数据之前应用的,用于过滤行级别的数据。例如,以下SQL语句使用WHERE子句检索orders表中价格大于100的订单:
SELECT * FROM orders WHERE price > 100;
而HAVING子句是在GROUP BY子句之后应用的,用于过滤分组级别的数据。例如,以下SQL语句使用HAVING子句检索orders表中按customer分组的订单中平均价格大于100的客户:
SELECT customer, AVG(price) as avg_price FROM orders GROUP BY customer HAVING AVG(price) > 100;
需要注意的是,使用HAVING子句时,必须先使用GROUP BY子句对数据进行分组,然后才能使用聚合函数来筛选数据。而WHERE子句则没有此限制,可以在任何时候使用。
OK 详细举个栗子
假设有一个orders表,包含订单编号、客户名称、订单日期和订单金额四个字段,数据如下:
order_id customer order_date amount
1 Alice 2022-01-01 100
2 Bob 2022-01-02 150
3 Alice 2022-01-03 200
4 Charlie 2022-01-04 120
5 Alice 2022-01-05 80
6 Bob 2022-01-06 90
使用WHERE子句和HAVING子句分别过滤数据:
使用WHERE子句过滤数据
SELECT * FROM orders WHERE amount > 100;
运行结果如下,只有订单编号为2、3、4的数据满足条件,返回了这三行数据:
order_id customer order_date amount
2 Bob 2022-01-02 150
3 Alice 2022-01-03 200
4 Charlie 2022-01-04 120
使用HAVING子句过滤数据
SELECT customer, AVG(amount) as avg_amount FROM orders GROUP BY customer HAVING AVG(amount) > 120;
运行结果如下,对customer字段进行分组,计算每个客户的平均订单金额,然后只返回平均订单金额大于120的客户,即Alice和Bob:
customer avg_amount
Alice 126.6667
Bob 120.0000
需要注意的是,HAVING子句中使用聚合函数时,不能直接使用别名,而需要使用聚合函数的名称。例如,上面的例子中使用的是AVG(amount),而不是avg_amount。