ON 、WHERE和HAVING区别

ON 、WHERE、HAVING都能通过限制条件筛选数据,但他们的使用及其不同。下面我们来分析三者之间的区别。

一、ON 和WHERE

        所有的查询都会产生一个中间临时报表,查询结果就是从返回临时报表中得到。 ON和WHERE后面所跟限制条件的区别,主要与限制条件起作用的时机有关: ON根据限制条件对数据库记录进行过滤,然后生产临时表; WHERE在临时表生产之后,根据限制条件从临时表中筛选结果。

         因为以上原因,ON和WHERE的区别主要有下: 1)  返回结果: 在左外(右外)连接中,ON会返回左表(右表)中的所有记录; 而WHERE中,此时相当于inner join,只会返回满足条件的记录(因为是从临时表中筛选,会过滤掉不满足条件的)。 例: 假设有两张表tab1,tab2,如下图:

两条SQL:

1、select * form tab1 left join tab2 on (tab1.size = tab2.size) where tab2.name=’AAA’;

2、select * form tab1 left join tab2 on (tab1.size = tab2.size and tab2.name=’AAA’);

2)  速度: ON限制条件发生时间较早,临时表的数据集要小,因此ON的性能要优于WHERE。

二. HAVING和WHERE

        HAVING和WHERE的区别也是与限制条件起作用时机有关。 HAVING是在聚集函数计算结果出来之后筛选结果,查询结果只返回符合条件的分组,HAVING不能单独出现,只能出现在GROUP BY子句中; WHERE是在计算之前筛选结果,如果聚集函数使用WHERE,那么聚集函数只计算满足WHERE子句限制条件的数据。

         例如: SELECT COUNT(id) FROM db_equip WHERE tb_equip_type = ‘2’; Count计算的结果是首先筛选设备类型为2的的设备,然后统计设备类型为2类型的数量。

        在使用和功能上,HAVING和WHERE有以下区别:

        1)HAVING不能单独出现,只能出现在GROUP BY子句之中;WHERE即可以和SELECT等其他子句搭配使用,也可以和GROUP BY子句搭配使用,WHERE的优先级要高于聚合函数高于HAVING。

         2)因为WHERE在聚集函数之前筛选数据,HAVING在计算之后筛选分组,因此WHERE的查询速度要比HAVING的查询速度快。

三、 总结        

        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中,`WHERE` `HAVING` 子句都用于过滤数据,但它们的作用阶段使用场景有显著区别。 `WHERE` 子句用于在执行 `GROUP BY` 之前过滤行数据。它适用于单个行的条件筛选,也就是说,它可以在数据被分组之前排除不符合条件的记录。例如,如果需要从一个员工表中选出所有工资高于5000的员工,可以使用 `WHERE` 来实现: ```sql SELECT * FROM employees WHERE salary > 5000; ``` 另一方面,`HAVING` 子句则用于在 `GROUP BY` 操作之后对聚合结果进行过滤。这意味着 `HAVING` 通常用来过滤由 `GROUP BY` 产生的组,这些组是基于一个或多个列的值进行合并后形成的。例如,如果需要找出那些平均工资超过10000的部门,可以这样写: ```sql SELECT department, AVG(salary) AS avg_salary FROM employees GROUP BY department HAVING AVG(salary) > 10000; ``` 值得注意的是,虽然 `WHERE` 可以在没有 `GROUP BY` 的情况下使用,但 `HAVING` 必须与 `GROUP BY` 一起使用。此外,`HAVING` 子句中的条件可以包含聚合函数,而 `WHERE` 子句则不能包含这样的函数[^1]。 关于 `ORDER BY` 的使用,它可以应用于最终的结果集,即使这个结果集是由两个 `SELECT` 语句的 `UNION` 操作生成的。然而,当涉及到 `HAVING` 子句时,不能直接将其与 `ORDER BY` 结合使用来排序结果集,因为 `HAVING` 是在 `GROUP BY` 后处理的,而 `ORDER BY` 则是在所有其他操作完成后才处理。 对于 `WHERE` `JOIN` 的关系,`ON` 子句用于定义连接两个表时的条件,而 `WHERE` 子句则用于过滤连接后的结果集。这意味着 `ON` 是在连接过程中用来决定哪些行应该被组合在一起,而 `WHERE` 是在连接完成后用来进一步筛选这些组合的结果[^2]。 最后,当涉及到窗口函数聚合函数时,`ORDER BY` 子句的使用需要特别小心。例如,在使用 `AVG()` 窗口函数时,`ORDER BY` 可以影响到窗口的范围,进而影响到计算出的平均值。如果在 `PARTITION BY` 后加上 `ORDER BY`,则会按照指定的顺序对每个分区内的数据进行排序,并据此计算累积统计信息[^3]。 综上所述,`WHERE` `HAVING` 在SQL查询中扮演着不同的角色,理解它们之间的差异对于编写高效、准确的SQL查询至关重要。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值