where和having的区别

WHEREHAVING 都是用于过滤数据的 SQL 子句,但它们的应用场景和工作方式有所不同:

1. WHERE 子句

  • 作用WHERE 用于过滤行数据,在数据库检索数据时先执行WHERE子句的过滤。
  • 位置:它出现在 SELECTUPDATEDELETE 语句中的数据提取阶段,在执行聚合函数(如 COUNT()SUM())之前进行过滤。
  • 使用场景WHERE 子句通常用于直接过滤列数据,不能用于过滤聚合后的结果。
  • 示例
    SELECT * FROM employees
    WHERE salary > 50000;
    
    此查询会过滤出 salary 大于 50000 的行数据。

2. HAVING 子句

  • 作用HAVING 用于过滤聚合结果,它在执行 GROUP BY 之后才进行过滤,主要用于聚合后的条件筛选。
  • 位置HAVING 子句必须出现在 GROUP BY 子句之后,用于过滤分组或聚合后的数据。
  • 使用场景HAVING 通常与聚合函数(如 COUNT()SUM())配合使用,过滤已经通过 GROUP BY 产生的分组结果。
  • 示例
    SELECT department, COUNT(*)
    FROM employees
    GROUP BY department
    HAVING COUNT(*) > 5;
    
    此查询会先按 department 分组,然后筛选出员工数量大于 5 的部门。

区别总结:

  • 处理时机

    • WHEREGROUP BY 和聚合运算之前应用,过滤行数据。
    • HAVINGGROUP BY 和聚合运算之后应用,过滤分组或聚合结果。
  • 使用限制

    • WHERE 不能用来过滤聚合函数的结果。
    • HAVING 可以使用聚合函数(例如 COUNTSUMAVG)。

例子对比:

假设我们有一个 sales 表,结构如下:

| id | product  | category | amount |
|----|----------|----------|--------|
| 1  | Apple    | Fruit    | 100    |
| 2  | Banana   | Fruit    | 50     |
| 3  | Carrot   | Vegetable| 200    |
| 4  | Lettuce  | Vegetable| 150    |

使用 WHERE

SELECT product, amount
FROM sales
WHERE amount > 100;
  • 输出:这将筛选出 amount 大于 100 的行,即 Carrot 和 Lettuce。

使用 HAVING

SELECT category, SUM(amount)
FROM sales
GROUP BY category
HAVING SUM(amount) > 150;
  • 输出:这将先按 category 分组,并计算每个类别的销售总额,然后筛选出总销售额大于 150 的类别。