on、where、having的区别

本文详细解释了在SQL查询中如何合理使用on、where和having来提高查询效率。通过对比三者的执行顺序及应用场景,帮助读者理解如何根据需求选择合适的条件过滤方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   on、where、having这三个都可以加条件的子句中,on是最先执行,where次之,having最后。有时候如果这先后顺序不影响中间结果的话,那最终结果是相同的。但因为on是先把不符合条件的记录过滤后才进行统计,它就可以减少中间运算要处理的数据,按理说应该速度是最快的。   
    
   根据上面的分析,可以知道where也应该比having快点的,因为它过滤数据后才进行sum,所以having是最慢的。但也不是说having没用,因为有时在步骤3还没出来都不知道那个记录才符合要求时,就要用having了。   
    
   在两个表联接时才用on的,所以在一个表的时候,就剩下where跟having比较了。在这单表查询统计的情况下,如果要过滤的条件没有涉及到要计算字段,那它们的结果是一样的,只是where可以使用rushmore技术,而having就不能,在速度上后者要慢。   
    
   如果要涉及到计算的字段,就表示在没计算之前,这个字段的值是不确定的,根据上篇写的工作流程,where的作用时间是在计算之前就完成的,而having就是在计算后才起作用的,所以在这种情况下,两者的结果会不同。   
    
   在多表联接查询时,on比where更早起作用。系统首先根据各个表之间的联接条件,把多个表合成一个临时表后,再由where进行过滤,然后再计算,计算完后再由having进行过滤。由此可见,要想过滤条件起到正确的作用,首先要明白这个条件应该在什么时候起作用,然后再决定放在那里。
SQL中,`HAVING` 和 `ON` 子句分别用于不同的查询阶段,且各自具有不同的功能和使用场景。 ### `ON` 子句的用法与特点 `ON` 子句主要用于 `JOIN` 操作中,用来指定两个表之间进行连接的条件。它在生成临时表之前应用,用于筛选参与连接的行。`ON` 子句通常用于多表连接操作中,例如 `INNER JOIN`、`LEFT JOIN` 等。其主要特点是: - 在连接操作之前执行,用于限制参与连接的行。 - 可以引用两个表中的列来定义连接条件。 - 不受 `GROUP BY` 影响,适用于连接阶段的行筛选。 例如,在以下查询中,`ON` 子句用于限制 `orders` 表和 `customers` 表之间的连接条件: ```sql SELECT * FROM orders JOIN customers ON orders.customer_id = customers.id; ``` ### `HAVING` 子句的用法与特点 `HAVING` 子句用于在 `GROUP BY` 分组操作之后对分组结果进行筛选。它通常与聚合函数一起使用,以过滤满足特定条件的分组。其主要特点是: - 在 `GROUP BY` 分组之后执行,用于筛选分组后的数据。 - 可以包含聚合函数(如 `SUM`、`COUNT`、`AVG` 等)。 - 不能替代 `WHERE` 子句用于原始数据的筛选。 例如,在以下查询中,`HAVING` 子句用于筛选订单总金额大于 1000 的客户: ```sql SELECT customer_id, SUM(order_amount) AS total_amount FROM orders GROUP BY customer_id HAVING SUM(order_amount) > 1000; ``` ### `HAVING` 与 `ON` 的区别 1. **执行时机不同** `ON` 子句在连接操作之前执行,用于确定哪些行参与连接;而 `HAVING` 子句在分组和聚合之后执行,用于筛选分组后的结果[^1]。 2. **作用对象不同** `ON` 用于连接两个表之间的行,作用于原始数据;`HAVING` 作用于分组后的聚合结果,通常与 `GROUP BY` 一起使用。 3. **支持的表达式类型不同** `ON` 可以引用两个表中的列来定义连接条件;`HAVING` 通常包含聚合函数,用于对分组后的结果进行筛选[^3]。 4. **应用场景不同** - `ON` 适用于多表连接时的条件定义。 - `HAVING` 适用于对分组统计结果进行过滤。 ### 示例对比 考虑以下两个查询: 1. 使用 `ON` 进行连接筛选: ```sql SELECT customers.name, SUM(orders.amount) AS total_spent FROM customers JOIN orders ON orders.amount > 100 WHERE customers.id = orders.customer_id GROUP BY customers.name; ``` 在此查询中,`ON` 限制了 `orders` 表中仅金额大于 100 的记录参与连接。 2. 使用 `HAVING` 进行分组后筛选: ```sql SELECT customer_id, COUNT(*) AS order_count FROM orders GROUP BY customer_id HAVING COUNT(*) > 5; ``` 在此查询中,`HAVING` 限制了最终结果中仅包含订单数量大于 5 的客户。 ### 总结 `ON` 和 `HAVING` 在SQL查询中分别承担不同的职责。`ON` 用于定义表连接的条件,作用于连接操作之前;而 `HAVING` 用于在分组和聚合后筛选分组结果,通常与 `GROUP BY` 一起使用。理解它们的执行顺序和适用场景对于编写高效、准确的SQL查询至关重要[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值