Select语句执行步骤

本文详细介绍了SQL查询的执行过程,包括Select语句的处理步骤、Union操作的限制与使用方法、多表查询的处理原则等核心内容。

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

由Select语句生成的查询结果是通过一个接一个应用它的字句来制定的。

 

首先应用From子句,

 

接着应用Where子句,

 

然后应用Select子句,

 

最后应用Order By子句来排序查询结果。

 

要生成Select语句的查询结果,请遵循下面的这些步骤

 

1.从From子句中提到的表开始

2.如果有一条Where子句,应用它的搜索条件到表的每一条记录,保留搜索条件为True的那些记录,并去掉搜索条件为False或NULL的那些记录。

3.对每个保留的记录,计算选择列表中每项的值,以生成一条查询结果记录。对于每个字段引用,使用当前记录中字段的值。

4.如果指定了Select Distinct,消除所生成的查询结果中的任何重复记录。

5.如果有一条Order By子句,按指定的那样排序查询结果。

 

使用Union的几个重要的限制:

两个表必须包含同样数目的字段

在第一个表中的数据类型必须与第二个表中对应字段的数据类型相同

两个表都不能用Order By子句排列。然而,组合后的查询结果可以排序

 


select MFR_ID,Product_id
from Products
where price > 2000.00
union
select distinct MFR,Product
from orders
where amount > 30000.00

(这个Union语句将按照默认的消除重复的记录)

 


select MFR_ID,Product_id
from Products
where price > 2000.00
union all
select distinct MFR,Product
from orders
where amount > 30000.00

(这句将不会消除重复的记录)

 

Union和排序

Order by 子句不能出现在由Union操作组合的两个select中,不管怎样,排序两个查询结果集没有太多的意义,因为它们被直接加入到UNION操作中,对用户是不可见的。然而,有UNION操作生成的组合的查询结果集可以通过在第二个select语句后指定一个Order by子句来排序。因为由Union操作生成的字段是没有命名的,Order By子句必须按字段编号指定字段。

 


select MFR_ID,Product_id
from Products
where price > 2000.00
union
select distinct MFR,Product
from orders
where amount > 30000.00

Order by 1,2

 

如果指定一个不带Where子句的量表查询,SQL产生连个表的积作为查询结果。

 

显示销售人员及其工作的城市的所有可能的组合

select name,city

from salesreps,offices

将生成salesreps和offices表的积,显示所有可能的销售人员/城市对。

 

多表查询处理原则:

1.如果语句是select语句的一个UNION,将第2步到第5步应用到每一条语句,以生成它们各自的查询结果。

2.形成在FROM子句中提到的表的乘积。如果FROM子句命名了一个表,则积就是那个表。

3.如果有一条WHERE子句,把它的搜索条件应用到积表的每一条记录,保留搜索条件为TRUE的那些记录(并去掉搜索条件为FALSE或NULL的那些记录)。

4.对于每个保留的记录,计算选择列表中每一项的值,以生成一条查询结果记录。对于每个字段引用,使用单签记录中字段的值。

5.如果指定了SELECT DISTINCT,消除所生成的查询结果中的任何重复的记录。

6.如果语句是SELECT语句的一个UNION,把各条语句的查询结果合并到一个查询结果表中。消除重复的记录,除非指定了UNION ALL。

7.如果存在一条ORDER BY子句,按指定的那样排序查询结果。

 

(基于SQL的DBMS实际上不会按这种方式执行查询,但是,前面定义的目的不是要描述DBMS是怎样执行查询的,相反,它构成了如何弄清楚一个特定的多表查询意味着什么的定义,即,它应该生成的查询结果集。)

 

查询执行顺序的扩展:

1.如果语句是SELECT语句的一个UNION,把第2步到第7不应用到每条语句,以生成它们各自的查询结果。

2.形成在FROM子句中命名的表的乘积。如果FROM子句命名了一个表,则积就是那个表。

3.如果有一条WHERE子句,应用它的搜索条件到积表的每一记录,保留其搜索条件为TRUE的那些记录。

4.如果有一条GROUP BY子句,把积表的剩余的记录安排到记录组中,以便每个组中的记录在所有的分组字段中有同样的值。

5.如果有一条HAVING子句,把它的搜索条件应用到每个记录组,保留其搜索条件为TRUE的那些组.

6.对于每个保留的记录(或记录组),计算选择列表中每一项的值,以生成一个查询结果记录。对一个简单的字段引用,使用单签记录(或记录组)中的字段值。对于一个字段函数,如果指定了GROUP BY,使用当前记录组作为它的参数;否则,使用全部的记录。

7.若果指定了SELECT DINSTINCT,则消除所生成的查询结果中任何重复的记录。

8.如果语句是SELECT语句的UNION,合并各个语句的查询结果到一个查询结果表中。消除重复的记录,除非指定了UNION ALL。

9.如果有ORDER BY子句,按指定顺序排序查询结果。

### SQL SELECT 语句执行顺序与逻辑 SQL 查询语句的实际执行顺序可能与其书写的语法顺序不同。以下是 SQL `SELECT` 语句的标准执行流程及其背后的逻辑: #### 实际执行顺序 尽管我们在书写 SQL 时遵循的是 `SELECT -> FROM -> JOIN -> WHERE -> GROUP BY -> HAVING -> ORDER BY -> LIMIT` 的顺序[^2],但在实际运行过程中,数据库引擎会按照以下顺序处理这些子句。 1. **FROM 和 JOIN**: 数据库首先从指定的数据表中读取数据并应用任何联接操作。这是为了构建初始的结果集。 2. **WHERE 过滤条件**: 接下来,数据库会对上一步生成的结果集施加过滤条件,仅保留满足特定条件的记录。 3. **GROUP BY 分组**: 如果存在分组需求,则在此阶段对数据进行聚合计算前的分组操作。 4. **HAVING 聚合筛选**: 对于已经完成分组后的结果集合,HAVING 子句进一步限定哪些分组可以进入最终输出范围之内。 5. **SELECT 投影字段选取**: 此时才真正决定要返回给用户的列名列表以及表达式的具体形式。 6. **DISTINCT 去重 (如果适用)**: 若有去重复的要求,在此步骤实现。 7. **ORDER BY 排序规则设定**: 结果集中每一行依据某个或某些键值大小关系重新排列位置次序。 8. **LIMIT 行数限制定义(可选)**: 最终确定最多能显示多少条符合条件的信息项数量上限。 以上描述了标准的关系型数据库管理系统如何解释和评估一个典型的结构化查询语言请求的过程概述[^3]。 ```sql -- 示例代码展示了一个完整的 SQL 查询过程 SELECT column_name(s) FROM table1 LEFT JOIN table2 ON table1.id = table2.foreign_id WHERE condition GROUP BY grouping_columns HAVING aggregate_condition ORDER BY sort_expression ASC/DESC LIMIT number_of_rows; ``` ### 注意事项 需要注意的是,虽然上述代表了一般情况下的执行路径,但不同的 DBMS 可能在内部机制上有细微差异,并且通过索引、缓存等技术手段可能会改变部分环节的表现特性。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值