mysql 中 where 、 group by 、having、order by 的执行顺序

本文介绍了MySQL查询过程中Where、GroupBy、Having及OrderBy等关键字的执行顺序,并解释了它们如何共同作用于查询结果。通过实际案例展示了如何利用这些关键字提高查询效率。

mysql中这些关键字是按照如下顺序进行执行的:Where, Group By, Having, Order by。

首先where将最原始记录中不满足条件的记录删除(所以应该在where语句中尽量的将不符合条件的记录筛选掉,这样可以减少分组的次数)

然后通过Group By关键字对视图进行分组 

接着根据Having关键字后面指定的筛选条件,将分组后不满足条件的记录筛选掉

最后按照Order By语句对视图进行排序,这样最终的结果就产生了。

having子句可以让我们筛选成组后的各种数据,where子句在聚合前先筛选记录,也就是说作用在group by和having子句前。而having子句在聚合后对组记录进行筛选。

having可以用聚合函数,如having sum(money) > 1000

SELECT user_type,is_admin ,SUM(id) FROM saut_m_user 
WHERE id > 100
GROUP BY user_type,is_admin
HAVING SUM(status) < 500
ORDER BY is_admin ASC


 

<think>好的,我现在需要回答用户关于MySQL查询语句中各子句实际执行顺序的问题。用户提到的子句包括from、where、inner join、select、group byhavingorder by和limit。首先,我要回忆一下自己之前学过的相关知识,并结合提供的引用内容来验证正确性。 根据用户提供的引用,特别是引用[1]和引用[2],里面提到了SQL的书写顺序执行顺序的不同。书写顺序通常是select、from、wheregroup byhavingorder by、limit,而执行顺序则不同。比如引用[1]提到执行顺序是from→wheregroup byhaving→select→order by→limit。同时,引用[2]也支持类似的说法,提到from接表名是一个子句,然后是wheregroup by等。 我需要确认这些步骤是否正确,并考虑是否有其他因素影响,比如join的处理。用户问题中提到了inner join,通常inner join属于from子句的一部分,因此执行顺序应该在from之后,where之前吗?或者说join的处理是在from阶段进行的? 比如,在from子句中,如果涉及到多表连接,比如inner join,那么这些连接操作是在from阶段处理的。所以执行顺序应该是先处理from中的表,包括所有的join操作,然后再应用where条件过滤。例如,当执行from table1 inner join table2 on condition时,首先进行连接,生成中间结果集,然后再应用where条件。 接下来,执行group by对结果进行分组,然后应用having子句过滤分组后的结果。之后是select子句选择需要的列,可能包括计算字段或聚合函数。之后进行order by排序,最后用limit限制返回的行数。 需要确认这些步骤是否符合引用中的内容。例如,引用[3]中的示例查询包含了inner join、group by、select等,其执行顺序应该是先执行from和inner join,然后group by,最后select。 另外,要区分书写顺序执行顺序的不同。用户可能容易混淆这两者,因为书写时select写在前面,但执行时from和join先处理。因此,在回答中需要明确指出执行顺序和书写顺序的不同,并举例说明。 还需要注意wherehaving的区别:where在分组前过滤行,而having在分组后过滤组。这也是执行顺序的一个关键点。 总结起来,执行顺序应为: 1. from(包括join) 2. where 3. group by 4. having 5. select 6. order by 7. limit 需要确保这个顺序正确,并引用提供的资料支持。例如,引用[1]明确指出执行顺序是from→wheregroup byhaving→select→order by→limit。这与我之前的理解一致,所以可以确认正确性。 现在,需要将这些内容以清晰的中文回答呈现,结构分明,并添加相关问题。同时,在适当的位置加入引用标识,如[^1]、[^2]等。</think>### MySQL查询子句的实际执行顺序 MySQL查询语句的实际执行顺序与书写顺序不同,以下是具体步骤: 1. **FROM子句(含JOIN)** 首先确定数据来源,处理表名和连接操作(如`INNER JOIN`)。例如,`FROM table1 INNER JOIN table2 ON condition`会先合并两表,生成中间数据集[^2]。 2. **WHERE子句** 对`FROM`生成的中间数据集进行行级过滤,筛选满足条件的记录[^2]。 3. **GROUP BY子句** 将过滤后的数据按指定列分组,为后续聚合函数(如`COUNT`、`SUM`)做准备[^3]。 4. **HAVING子句** 对分组后的结果进行过滤,仅保留满足条件的分组。与`WHERE`不同,`HAVING`作用于分组后的数据[^3]。 5. **SELECT子句** 选择最终输出的列,可能包含计算字段或聚合函数(如`COUNT(e_name)`)。此时别名才生效[^2]。 6. **ORDER BY子句** 对`SELECT`的结果进行排序,默认升序(`ASC`),可指定降序(`DESC`)[^1]。 7. **LIMIT子句** 限制返回的行数,常用于分页[^3]。 ### 示例说明 假设执行以下查询: ```sql SELECT d_name 部门, COUNT(e_name) 员工人数 FROM employee INNER JOIN dept ON dept.dept_no = employee.dept_no WHERE salary > 5000 GROUP BY dept.dept_no HAVING COUNT(e_name) > 3 ORDER BY 员工人数 DESC LIMIT 2; ``` **执行顺序**: 1. `FROM employee INNER JOIN dept` 连接两表 2. `WHERE salary > 5000` 过滤工资大于5000的员工 3. `GROUP BY dept.dept_no` 按部门分组 4. `HAVING COUNT(e_name) > 3` 筛选员工数大于3的部门 5. `SELECT` 选择部门名称和员工人数 6. `ORDER BY 员工人数 DESC` 按人数降序排序 7. `LIMIT 2` 返回前2条结果[^3]。 ### 常见误区 - **WHERE vs HAVING**:`WHERE`过滤行,`HAVING`过滤分组。 - **别名使用**:`SELECT`中定义的别名(如“员工人数”)只能在`ORDER BY`或`HAVING`之后使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值