sql语句的执行顺序

本文详细解析了SQL查询语句的执行流程,从from、join、where到groupby、聚合函数、having、select、distinct、orderby和limit的顺序。通过实例展示了如何使用这些语句进行数据筛选、分组聚合和排序限制。了解这一执行顺序对于优化SQL查询性能至关重要。

from>join>where>group by>聚合函数>having>select>order by>limit

1、最先执行from table;

需要先确定从哪个表中取数据,所以最先执行from table。

2、join连接

用于把来自两个或多个表的行结合起来,简单补充一下连接的类型

  • 自然连接(natural join)
  • 内连接(inner join):内连接查询能将左表和右表中能关联起来的数据连接后返回,返回的结果就是两个表中所有相匹配的数据
  • 外连接(outer join):外连接分为左外连接(LEFT JOIN:即使右表中没有匹配,也从左表返回所有的行)、右外连接(RIGHT JOIN:即使左表中没有匹配,也从右表返回所有的行)、还有一个FULL JOIN(全连接),不过MYSQL不支持全连接
  • 交叉连接(cross join)即笛卡尔连接

3、where语句;

where语句是对条件加以限定

4、分组语句【group by…… having】;

group by是分组语句

having是和group by配合使用的,用来作条件限定

5、聚合函数;

常用的聚合函数有max,min, count,sum,聚合函数的执行在group by之后,having之前

举例:count函数查询分组后,每一组分别有多少条数据

select count(*) from user group by gender

值得注意的是:聚合函数的执行在group by之后,having之前

6、select语句;

对分组聚合完的表挑选出需要查询的数据

7、Distinct

distinct对数据进行去重

如果sql语句存在聚合函数,例如count、max等,会先执行聚合函数再去重

8、order by排序语句。

order by排序语句

select * from user order by id  升序排序
select * from user order by id desc 降序排序

9、limit

limit用于指定返回的数据条数

select * from user limit 2
从user表中查询前两条数据
该sql等同于
select * from user limit 0,2
表示从第0条开始取两条数据

limit常配合order by使用

select * from user order by id limit 3
根据id排序,选出id排序前三的数据

总结

from>join>where>group by>聚合函数>having>select>order by>limit

例子

select 
distinct user.name 
from user 
join vip on user.id=vip.id 
where user.id>10 
group by user.mobile 
having count(*)>2 
order by user.id
limit 3;

执行顺序

  1. from user
  2. join vip on user.id=vip.id ,join是表示要关联的表,on是连接的条件
  3. where user.id>10
  4. group by user.mobile 根据user.mobile分组
  5. 然后先执行count(*)在执行having,查询分组之后数量大于2的分组数据
  6. select 对分组聚合完的表挑选出需要查询的数据
  7. distinct查询出来的数据去重
  8. order by user.id 对去重后的数据排序
  9. limit 3对排序后的数据选出前面3条
<think>好的,用户想了解SQL语句执行顺序。我之前在回答里已经整理过相关引用,现在需要结合这些引用内容来详细解析。首先,我需要回忆每个引用的内容,确保正确引用。 根据引用[2],SQL执行顺序是从FROM开始,然后是ON、JOIN、WHERE、GROUP BY、HAVING、SELECT、DISTINCT、ORDER BY,最后是LIMIT/OFFSET。这个顺序很重要,因为每一步都是基于前一步的结果进行处理。比如WHERE子句在GROUP BY之前执行,这样可以在分组前过滤数据,提高效率,如引用[4]提到的,非Oracle数据库可以通过WHERE减少GROUP BY处理的数据量。 然后引用[3]提到HAVING用于过滤聚合值,而WHERE不能和聚合函数一起使用,所以HAVING必须跟在GROUP BY之后。这解释了为什么HAVING的执行顺序在WHERE之后。 还需要注意SELECT子句虽然在语法中靠前,但实际执行较晚,是在WHERE、GROUP BY之后。这可能让用户混淆,需要明确说明执行顺序和书写顺序的不同。 另外,引用[1]提到SQL语句的大小写会影响解析,虽然与执行顺序无关,但需要注意编码规范,避免不必要的解析开销。 用户的问题是关于执行顺序的解析,所以重点放在各关键字的执行步骤,并结合例子说明。比如FROM确定数据源,WHERE过滤行,GROUP BY分组,HAVING过滤组,SELECT选择列,ORDER BY排序,最后LIMIT限制结果数量。 可能用户在实际优化SQL时遇到性能问题,比如WHERE和HAVING的使用不当导致效率低下,或者ORDER BY消耗资源过多。需要强调优化建议,如尽早过滤数据,减少中间结果集的大小。 还需要注意不同数据库可能有细微差异,比如引用[4]提到非Oracle的情况,但用户可能使用的是其他数据库,所以需要保持通用性,同时指出可能的差异。 最后,生成相关问题时要围绕执行顺序的影响因素、优化技巧、常见错误等方面提问,帮助用户深入理解。</think>### SQL语句执行顺序详解(标准解析) SQL语句执行顺序与书写顺序不同,具体流程如下(按执行步骤编号): 1. **FROM/JOIN** 确定数据来源,包括表的连接操作。首先执行笛卡尔积,再通过ON条件筛选连接结果。 $$ \text{虚拟表VT1 = 基础表组合} $$ [^2][^4] 2. **ON(连接条件过滤)** 对连接后的临时表进行初步筛选,仅保留满足连接条件的记录。 $$ \text{虚拟表VT2 = VT1中满足ON条件的记录} $$ [^4] 3. **WHERE(行级过滤)** 对连接后的数据进行行级过滤,此阶段**不能使用聚合函数**。 $$ \text{虚拟表VT3 = VT2中满足WHERE条件的记录} $$ [^4] 4. **GROUP BY(分组)** 对数据进行分组,生成以分组列为单位的聚合数据。 $$ \text{虚拟表VT4 = 按指定列分组的聚合结果} $$ [^3] 5. **HAVING(组级过滤)** 对分组后的数据进行筛选,**可使用聚合函数**。 $$ \text{虚拟表VT5 = VT4中满足HAVING条件的组} $$ [^3] 6. **SELECT(选择列)** 确定最终输出的列,可进行列计算或别名定义。 $$ \text{虚拟表VT6 = 从VT5中选择指定列} $$ [^2] 7. **DISTINCT(去重)** 对SELECT结果进行去重处理。 $$ \text{虚拟表VT7 = VT6去重后的结果} $$ [^2] 8. **ORDER BY(排序)** 对结果集进行排序,生成游标(非物理表),**资源消耗较大**。 $$ \text{游标VC8 = 按指定列排序后的结果} $$ [^2] 9. **LIMIT/OFFSET(结果限制)** 最终截取需要返回的数据行。 $$ \text{最终结果集 = VC8中指定范围的记录} $$ [^2] ### 关键差异说明 - **WHERE vs HAVING**:WHERE在分组前过滤单行数据,HAVING在分组后过滤整组数据[^3][^4] - **执行顺序优化**:在WHERE阶段过滤更多数据可显著提升性能(减少后续处理的数据量)[^4] - **ORDER BY代价**:排序操作需要完整结果集,大数据量时建议通过索引优化[^2] ### 示例验证 ```sql SELECT department, AVG(salary) as avg_sal FROM employees WHERE hire_date > '2020-01-01' GROUP BY department HAVING AVG(salary) > 10000 ORDER BY avg_sal DESC LIMIT 5 ``` 执行步骤: 1. 从`employees`表取数据 2. 筛选`hire_date > 2020-01-01`的记录 3. 按`department`分组计算平均工资 4. 过滤出平均工资>10000的组 5. 选择部门名称和平均工资列 6. 按平均工资降序排列 7. 返回前5条记录
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值