SQL语句中where,group by,order by,having关键词执行顺序?

本文探讨了SQL语句在Oracle与MySql中的执行顺序差异,重点讲解了where、group by、having及order by的执行流程,并介绍了如何通过合理安排多表联查中的表顺序来提高查询效率。

先上答案:where -> group by -> having -> order by

1.涉及知识点

这里涉及一个Oracle和MySql的区别,Oracle中having不能单独使用即使在没有where的情况下也不行,会有如下报错
在这里插入图片描述
而在MySql中则不会
在这里插入图片描述
所以得出结论:Oracle中having严格执行他是分组过滤的功能必须搭配group by使用;MySql中则同样把having视为二级过滤但可以不搭配group by。

2.拓展知识(另外一个顺序问题)

在多表联查的时候from后面多个表的顺序会影响这条查询sql的执行效率,按照从右到左的顺序处理FROM子句中的表名,因此FROM子句中写在最后的表(基础表 driving table)将被最先处理。

where也有相同的机制,也是从右向左处理。

我们在进行多表联查的时候要依据这样的机制,在写from的时候根据表数据量的多少,将数据量相对较少的放在后面;在写where条件的时候要把选择性强的条件放到最后,这样第一次过滤的时候就过滤掉了大部分无用数据,使得接下来执行前面的过滤条件是效率更高。

注意!having使用方面不同数据库有区别

SELECT system_code,COUNT(system_code) AS num  
FROM trade 
GROUP BY system_code HAVING num > 100;

mysql像上面这样写没有问题,如果是Oracle数据库就会报ORA-00936:表达式缺失的错误

Oracle数据库需要用如下写法

SELECT system_code,COUNT(system_code) AS num  
FROM trade 
GROUP BY system_code HAVING COUNT(system_code) > 100;
MySQL 查询语句中 `WHERE`、`GROUP BY` 和 `ORDER BY` 等子句执行顺序是由数据库引擎内部机制决定的,其实际执行顺序与书写顺序存在差异,理解这一顺序对于优化查询性能至关重要。 1. **FROM 子句** 查询执行的第一步是确定数据来源,即从哪个表或视图中获取数据。这一步会加载表中的原始数据供后续操作使用[^2]。 2. **WHERE 子句** 在加载数据之后,`WHERE` 子句会对这些数据进行初步过滤,只保留满足条件的数据行。这一步的结果集将作为后续操作的基础。例如,`WHERE ProductPlace = 'china'` 会筛选出所有产地为中国的产品记录[^4]。 3. **GROUP BY 子句** 接下来,`GROUP BY` 子句会根据指定的列对数据进行分组。每个分组将包含一组具有相同值的行。这一步的结果是一个分组后的数据集,每个分组通常会结合聚合函数(如 `SUM`、`COUNT`、`AVG` 等)来计算统计数据。 4. **HAVING 子句** `HAVING` 子句用于对分组后的结果集进行进一步的过滤。它与 `WHERE` 子句不同,`WHERE` 是在分组前对原始数据进行过滤,而 `HAVING` 是在分组后对分组结果进行过滤。例如,可以使用 `HAVING COUNT(*) > 5` 来筛选出包含超过5条记录的分组[^1]。 5. **SELECT 子句** 在分组和过滤完成后,`SELECT` 子句将决定最终返回的列。此时,可以使用聚合函数来生成最终的查询结果。需要注意的是,除了聚合函数外,`SELECT` 中的列必须出现在 `GROUP BY` 子句中,否则会导致错误[^2]。 6. **ORDER BY 子句** 最后,`ORDER BY` 子句会对最终的结果集进行排序。排序可以是升序(默认)或降序。MySQL 有两种方式实现排序:一种是通过索引扫描排序,另一种是通过文件排序(filesort)。索引扫描排序通常更快,因为它利用了索引的有序性;而文件排序则需要将数据加载到内存中进行排序,适用于没有合适索引的情况[^3]。 ### 示例代码 以下是一个包含 `WHERE`、`GROUP BY` 和 `ORDER BY` 的 SQL 查询示例: ```sql SELECT FruitName, ProductPlace, COUNT(*) AS Total FROM T_TEST_FRUITINFO WHERE ProductPlace = 'china' GROUP BY FruitName, ProductPlace ORDER BY Total DESC; ``` - **执行顺序**: 1. `FROM T_TEST_FRUITINFO`:从表中加载所有数据。 2. `WHERE ProductPlace = 'china'`:筛选出所有产地为中国的产品记录。 3. `GROUP BY FruitName, ProductPlace`:按水果名称和产地进行分组。 4. `SELECT FruitName, ProductPlace, COUNT(*) AS Total`:计算每个分组的数量。 5. `ORDER BY Total DESC`:按数量降序排列最终结果。 ### 总结 MySQL 查询的执行顺序如下: 1. `FROM` 2. `WHERE` 3. `GROUP BY` 4. `HAVING` 5. `SELECT` 6. `ORDER BY` 理解这一顺序有助于编写高效的 SQL 查询,并能够更好地优化数据库性能。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值