oracle 连接 中的 ON 和WHERE

本文通过具体的SQL示例,介绍了如何使用左连接(LEFT JOIN)及WHERE子句进行数据检索。通过对比不同条件下左连接的行为,展示了WHERE子句在筛选结果集中的作用。

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

前提准备


CREATE TABLE A_TEST
(
A_ID VARCHAR2(100) NOT NULL,
A_C1 VARCHAR2(100)
)

数据:
1 A1
2 A2
3 A3

CREATE TABLE B_TEST
(
B_ID VARCHAR2(100) NOT NULL,
B_C1 VARCHAR2(100),
B_C2 VARCHAR2(100)
)
数据:

1 BC1_1 B_C2_1
2 BC1_2 B_C2_2
3 BC1_3 B_C2_3




LEFT JOIN ON


SELECT A.A_C1
,B.B_C1
,B.B_C2
FROM A_TEST A
LEFT JOIN B_TEST B ON A.A_ID=B.B_ID

检索结果:
A1 BC1_1 B_C2_1
A2 BC1_2 B_C2_2
A3 BC1_3 B_C2_3




LEFT JOIN ON 附件条件


SELECT A.A_C1
,B.B_C1
,B.B_C2
FROM A_TEST A
LEFT JOIN B_TEST B ON A.A_ID=B.B_ID
[color=red][b]AND A.A_ID = '1'[/b][/color]

检索结果:
A1 BC1_1 B_C2_1
A2 (NULL) (NULL)
A3 (NULL) (NULL)



LEFT JOIN ON WHERE


SELECT A.A_C1
,B.B_C1
,B.B_C2
FROM A_TEST A
LEFT JOIN B_TEST B ON A.A_ID=B.B_ID
WHERE A.A_ID='1'

检索结果:A1 BC1_1 B_C2_1


※: 其实WHERE 就是和我们没有联合条件是一样过滤 带WHERE的联合就是把联合后的结果在从新过滤一遍而已!
<think>嗯,用户问的是Oracle SQL中ONWHERE在过滤条件时的区别。首先,我需要回忆一下ONWHERE在SQL查询中的作用。记得ON是用于连接表的条件,而WHERE是用于过滤结果集的。不过用户可能想知道更具体的区别,特别是在不同的连接类型下,比如内连接连接。 根据引用[3]提到的,left join、right join、full join这些外连接的情况下,不管ON的条件是否为真,都会返回左表或右表的所有记录。而inner join的话,ONWHERE的效果可能是一样的。不过这可能不完全准确,需要再仔细想想。 比如,当使用LEFT JOIN时,如果在ON里加条件,即使条件不满足,左表的记录还是会保留,而右表的部分会用NULL填充。但如果把同样的条件放在WHERE里,那么不满足条件的记录会被过滤掉,导致左表中不符合条件的记录也被排除,这样可能就不是LEFT JOIN的效果了。引用[2]也提到,外连接时,条件放在WHERE子句可能导致数据丢失,所以应该放在ON里。 那内连接的话,比如INNER JOINONWHERE的区别可能不大,因为内连接本身就会根据ON条件来匹配,但如果在ON里加额外的条件,可能影响连接的结果,而WHERE则是在连接后的结果上进行过滤。不过引用[3]说inner join情况下,ONWHERE的结果集是相同的,这可能是指当ON的条件WHERE的条件都是针对连接条件时,结果相同?还是说有其他情况? 比如,假设有一个INNER JOINON的条件是A.id = B.id AND B.some_col = 1,而另一个情况是INNER JOIN ON A.id = B.id,然后在WHERE里加上B.some_col = 1。这两种情况的结果是否相同?可能相同,因为内连接会先根据ON的条件匹配,然后WHERE过滤。但是如果ON中的条件影响了连接的行,而WHERE的条件进一步过滤,这时候可能会有不同的结果吗? 不过根据引用[3],inner join时条件放在ONWHERE结果相同,可能是在某些情况下,比如当ON的条件只是等值连接,而WHERE的条件是额外的过滤。但如果是更复杂的条件,可能会有不同?需要具体例子来说明。 用户可能需要知道何时使用ON,何时使用WHERE,特别是在外连接的情况下。例如,当需要保留主表的所有记录时,即使从表不符合条件,应该把条件放在ON里,而不是WHERE里,否则会导致主表的记录被过滤掉。 另外,引用[1]中提到,编写查询时,有时候放在ONWHERE的结果看起来一样,但其实在特定情况下会有差异。所以需要明确两者的执行顺序适用范围。 总结一下,区别主要在于连接类型:外连接时,ON条件影响连接过程,保留主表数据;WHERE条件在连接后过滤,可能导致主表数据丢失。而内连接时,ONWHERE可能效果相同,因为内连接本身就会过滤不匹配的行。 还需要考虑性能方面,比如条件放在ON可能在连接过程中提前过滤,减少连接的数据量,而WHERE是在连接后过滤,可能效率稍低。不过这可能取决于优化器的处理方式。 最后,用户可能需要示例来理解不同情况下的结果差异,所以回答中应该包含具体的例子,比如LEFT JOINONWHERE的区别,以及INNER JOIN时的对比。</think>### Oracle SQL中ONWHERE过滤条件的区别 在Oracle SQL中,`ON``WHERE`虽然都用于筛选数据,但**作用阶段适用场景不同**,尤其在多表连接时差异显著。 --- #### 1. **作用阶段的区别** - **`ON`子句**: 用于定义**表连接的条件**,属于连接操作的一部分。它在生成临时结果集时生效,直接影响哪些行会被连接。 - **外连接(LEFT/RIGHT/FULL JOIN)**:即使`ON`中的条件不满足,主表数据仍会被保留,从表字段以`NULL`填充[^3]。 - **内连接(INNER JOIN)**:`ON`条件仅筛选满足条件的行进行连接。 - **`WHERE`子句**: 在连接完成后对结果集进行**最终过滤**。它会剔除所有不满足条件的行,无论主表还是从表的数据[^2]。 --- #### 2. **外连接中的典型差异** **示例场景**: 表`employees`(员工表)`departments`(部门表),使用`LEFT JOIN`查询所有员工及其部门信息。 - **条件放在`ON`中**: ```sql SELECT e.name, d.department_name FROM employees e LEFT JOIN departments d ON e.department_id = d.department_id AND d.department_name = 'IT'; ``` **结果**:所有员工都会被列出,但仅`department_name='IT'`的部门信息显示,非IT部门的员工对应字段为`NULL`。 - **条件放在`WHERE`中**: ```sql SELECT e.name, d.department_name FROM employees e LEFT JOIN departments d ON e.department_id = d.department_id WHERE d.department_name = 'IT'; ``` **结果**:仅保留部门为`IT`的员工,其他员工因`WHERE`过滤而被剔除。 --- #### 3. **内连接中的等效性** 对于`INNER JOIN`,`ON``WHERE`的筛选效果通常一致: ```sql -- 方式1:条件在ON中 SELECT * FROM tableA INNER JOIN tableB ON tableA.id = tableB.id AND tableB.status = 1; -- 方式2:条件在WHERE中 SELECT * FROM tableA INNER JOIN tableB ON tableA.id = tableB.id WHERE tableB.status = 1; ``` **两者结果相同**,因为内连接会先按`ON`条件匹配,再隐式应用`WHERE`过滤[^3]。 --- #### 4. **性能与最佳实践** - **外连接**:若需保留主表数据,将过滤条件放在`ON`中;若需过滤结果,使用`WHERE`。 - **动态条件**:复杂筛选可通过动态SQL拼接`WHERE`条件,但需注意临时表的使用(如引用[^4]提到的`EXECUTE IMMEDIATE`)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值