sql(join on 和where的执行顺序

sql(join on 和where的执行顺序

left join :左连接,返回左表中所有的记录以及右表中连接字段相等的记录。

right join :右连接,返回右表中所有的记录以及左表中连接字段相等的记录。

inner join: 内连接,又叫等值连接,只返回两个表中连接字段相等的行。

full join:外连接,返回两个表中的行:left join + right join。

cross join:结果是笛卡尔积,就是第一个表的行数乘以第二个表的行数。

关键字: on

数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户。

在使用left jion时,on和where条件的区别如下:

1、 on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回左边表中的记录。

2、where条件是在临时表生成好后,再对临时表进行过滤的条件。这时已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。

假设有两张表:

表1:tab2

idsize
110
220
330

表2:tab2

sizename
10AAA
20BBB
20CCC

两条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’)

第一条SQL的过程:

 

1、中间表
on条件:
tab1.size = tab2.size
tab1.idtab1.sizetab2.sizetab2.name
11010AAA
22020BBB
22020CCC
330(null)(null)

 

  
2、再对中间表过滤
where 条件:
tab2.name=’AAA’
tab1.idtab1.sizetab2.sizetab2.name
11010AAA

 

  

 

第二条SQL的过程:

 

1、中间表
on条件:
tab1.size = tab2.size and tab2.name=’AAA’
(条件不为真也会返回左表中的记录)
tab1.idtab1.sizetab2.sizetab2.name
11010AAA
220(null)(null)
330(null)(null)

 

 

其实以上结果的关键原因就是left join,right join,full join的特殊性,不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。 而inner jion没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。

转载于:https://www.cnblogs.com/atwanli/articles/8067315.html

<think>好的,我现在需要帮助用户解析SQLJOINON关键字的执行顺序。用户的问题是关于JOINONSQL中的执行顺序,我需要先回忆相关的知识,并结合提供的引用内容来构建一个准确的回答。 首先,根据引用[2],SQL执行顺序是:FROM → WHERE → GROUP BY → HAVING → SELECT → ORDER BY。但这里涉及到JOINON的情况,需要更详细的分析。通常,JOIN属于FROM子句的一部分,而ON条件是在JOIN过程中应用的过滤条件。因此,JOIN执行应该在WHERE子句之前,因为FROMJOIN是在执行WHERE之前的步骤。 接下来,ON条件的作用类似于JOIN时的连接条件,它决定了如何将两个表的行组合在一起。而WHERE子句则是在JOIN之后对结果进行过滤。例如,如果使用LEFT JOINON中的条件会影响哪些右表的行被匹配到左表,而WHERE子句则会过滤掉整个连接后的结果中的行,可能导致左表中未匹配的行被排除,从而将LEFT JOIN的效果变成类似INNER JOIN的情况。这一点需要特别注意,因为用户可能在写查询时混淆ONWHERE的使用,导致结果不符合预期。 然后,考虑引用[3]中的例子,子查询在FROM子句中,这说明子查询的执行是在外部查询的FROM阶段进行的。同样,JOIN操作作为FROM的一部分,其执行顺序应优先于WHERE、GROUP BY等其他子句。因此,ON条件作为JOIN的一部分,会在JOIN处理时被应用,而WHERE则是在整个JOIN完成之后应用的过滤条件。 接下来需要验证这些理解是否正确。例如,当执行一个带有JOINON条件的查询时,执行顺序应该是先处理FROM中的表,执行JOIN并应用ON条件,然后再处理WHERE子句。因此,ON条件JOIN过程中起作用,而WHERE在之后过滤结果集。这解释了为什么在LEFT JOIN中使用WHERE可能导致行被过滤掉,而ON条件则不会影响左表的所有行,只会影响匹配的部分。 此外,需要提醒用户注意在使用不同JOIN类型时,ONWHERE的不同影响。例如,INNER JOINONWHERE的效果可能看起来相似,但对于OUTER JOIN(如LEFT JOIN),两者的区别就变得重要了。正确的使用可以确保查询结果符合预期,避免数据丢失或错误的结果。 最后,总结执行顺序:FROM(包括JOINON)→ WHERE → GROUP BY → HAVING → SELECT → ORDER BY。需要强调JOINON在FROM阶段处理,而WHERE在之后,所以ON条件影响连接过程,WHERE影响连接后的结果。同时,结合引用中的内容,确保引用标记正确,例如引用[2]引用[3]来支持解释。</think>### SQLJOINON关键字的执行顺序解析 在SQL查询中,`JOIN``ON`的执行顺序属于**FROM子句处理阶段**,具体步骤如下: 1. **FROM阶段**:首先执行`FROM`子句中的所有表关联操作,包括`JOIN`及其`ON`条件。 - `JOIN`会根据`ON`中定义的连接条件匹配左右表的行。例如,`LEFT JOIN`会保留左表所有记录,仅用`ON`条件筛选右表的匹配行[^2]。 - `ON`条件仅作用于关联表的匹配过程,而不会过滤最终结果集。例如: ```sql SELECT * FROM table1 LEFT JOIN table2 ON table1.id = table2.id AND table2.status = 1 ``` 即使`table2.status`不满足条件,`table1`的所有行仍会保留,但`table2`的对应字段可能为`NULL`。 2. **WHERE阶段**:在`JOIN`完成后,`WHERE`子句会对连接后的临时结果集进行过滤。 - 如果`WHERE`条件中包含对右表字段的限制(如`WHERE table2.status = 1`),可能导致`LEFT JOIN`退化为类似`INNER JOIN`的效果,因为未匹配的右表行会被过滤掉[^3]。 ### 关键区别 - **ON条件**:影响`JOIN`过程中表的匹配逻辑,不直接过滤最终结果。 - **WHERE条件**:对所有关联完成后的数据进行最终过滤。 ### 示例对比 ```sql -- 示例1:ON中过滤右表,保留左表所有行 SELECT * FROM orders LEFT JOIN customers ON orders.customer_id = customers.id AND customers.country = 'USA'; -- 示例2:WHERE中过滤,可能导致左表数据丢失 SELECT * FROM orders LEFT JOIN customers ON orders.customer_id = customers.id WHERE customers.country = 'USA'; ``` - **示例1**中,左表`orders`的所有订单都会显示,但仅关联`country='USA'`的客户。 - **示例2**中,`WHERE`会过滤掉右表不满足条件的行,导致左表未匹配的行也被移除[^2]。 ### 总结顺序 完整执行顺序为: $$ \text{FROM → ONJOINWHERE → GROUP BY → HAVING → SELECT → ORDER BY} $$
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值