SQL中的join on和where条件的先后顺序

这几天在项目中使用到了视图,感觉还不错,但是今天发现单纯的依靠并表形成的视图,无法很好的完成特定的任务,比如说有一部分数据不管相关联的数据有没有,必须展现出来的(可能我的SQL不是很好,如果哪位达人有好的实现方式,欢迎指教,非常感谢)

于是,我就想到了左连结,并且右表先过滤一次再进行连接

SQL 语句如下:

 

select * from table1 as a left join table2 as b on a.tid=b.tid where a.parentid='' and b.years=2010
执行之后,发现还是不太符合要求,查不出数据,于是乎,调整了下代码:
select * from table1 as a left join table2 as b on a.tid=b.tid and b.years=2010 
where a.parentid='' 
测试了一下,符合要求的数据呈现出来了,感觉可以把过滤右表的条件放在where 前执行比较靠谱,放在 where后 是对并表后的数据查询。

转载于:https://www.cnblogs.com/MrWby/archive/2010/04/14/1712206.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、付费专栏及课程。

余额充值