左连接的左边为什么不全显示

left join后面加上where条件浅析

select a.*,b.*
from table1 a
left join table2 b on b.X=a.X
where XXX

如上:一旦使用了left join,没有where条件时,左表table1会显示全部内容

    使用了where,只有满足where条件的记录才会显示(左表显示部分或者全部不显示)

so。。。。

left join的困惑:一旦加上where条件,则显示的结果等于inner join 

原因分析:

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

where条件是在临时表生成好后,再对临时表进行过滤的条件;

因此:where 条件加上,已经没有left join的含义(必须返回左边表的记录)了,条件不为真的就全部过滤掉。 

解决方案:

1、where过滤结果作为子查询,和主表left,如下:

复制代码

select a.*,tmp.*
from table1 a
left join(
    select a.*,b.*
    from table1 a
    left join table2 b on b.X=a.X
    where XXX
)tmp

复制代码

很明显,子查询语句无论 left join、inner join都没啥区别了

2、查询条件放在on后面

1

2

3

select a.*,b.*

from table1 a

left join table2 b on b.X=a.X and XXX

注意:where XXX去掉,改为链接条件on后面的 and XXX

分析:

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

结论 a表和b表 做关联 

1. on a.id=b.id and a.name='张三' 这种在on后边直接and 的对a表无效  只要不加where 左边永远都是全显示    

2.on a.id=b.id where a.name='张三' 这种则查出只有是张三的数据

<think> 我们正在讨论Oracle中的左连接(LEFT JOIN)行为。用户的问题是:“Oracle左连接是否会显示满足查询条件的结果?”这里需要区分两个关键点: 1. 左连接本身的特性:左连接会返回左表的所有行,即使右表中没有匹配的行(此时右表部分为NULL)。 2. 查询条件的位置:条件放在ON子句和WHERE子句中的同影响。 根据引用[1]:左连接保留左边主表的所有行(即使在右表没有匹配的行),右表输出满足ON条件的行,满足的输出NULL。 因此,我们需要明确: - 当条件放在ON子句中时:左表的所有行都会被保留,而右表则根据条件进行匹配,满足条件的右表行会显示为NULL。 - 当条件放在WHERE子句中时:由于WHERE子句是在连接之后进行过滤,它会对连接后的结果进行过滤。如果右表的列在WHERE子句中被要求为非NULL(即要求右表匹配),那么左表中那些在右表没有匹配的行(即右表部分为NULL的行)就会被过滤掉,因为NULL满足任何条件(除非条件显式检查NULL)。 所以,用户的问题的答案是:左连接会保留左表的所有行,但是否显示这些行(特别是当它们满足某些条件时)取决于条件放置的位置。 具体来说: 1. 如果条件是对右表的限制,并且放在ON子句中:左表的所有行都会显示,右表满足条件的行显示为NULL。 2. 如果条件放在WHERE子句中:则左表中那些在右表没有匹配的行(即右表部分为NULL)可能会因为WHERE条件而被过滤掉(除非条件允许NULL)。 举例说明: 假设有两个表:Person(主表)和Address(从表),我们想获取所有人的地址信息,但只想要地址是'New York'的人,同时保留所有人。 错误做法(将条件放在WHERE子句): ```sql SELECT p.Name, a.City FROM Person p LEFT JOIN Address a ON p.AddressId = a.AddressId WHERE a.City = 'New York'; ``` 这样写的话,左表中那些没有地址或者地址不是'New York'的人都会被过滤掉,因为他们的a.City为NULL(满足a.City='New York')。 正确做法(将条件放在ON子句): ```sql SELECT p.Name, a.City FROM Person p LEFT JOIN Address a ON p.AddressId = a.AddressId AND a.City = 'New York'; ``` 这样,左表的所有人都会被保留,而只有地址是'New York'的地址信息才会被显示,其他人地址显示为NULL。 因此,回答用户的问题:Oracle左连接显示左表的所有行,即使右表没有匹配的行(即满足ON条件中的匹配条件),但是,如果对右表有额外的条件并且放在WHERE子句中,则可能会导致这些行被过滤掉。 引用[3]中展示了一个左连接的例子,其中条件放在ON子句,因此保留了左表的所有行,即使右表没有匹配(此时右表字段为NULL)。 结论:左连接保证左表的所有行都会被返回,但右表的显示取决于ON条件和WHERE条件的位置。如果希望保留左表所有行,对右表的条件应放在ON子句中;如果放在WHERE子句中,则可能过滤掉左表中在右表没有匹配的行。 相关问题: 1. 在Oracle左连接中,ON子句和WHERE子句的条件有什么区别? 2. 如何确保左连接查询中左表的所有行都被返回? 3. 在左连接中,如何过滤右表的数据影响左表行数的显示? </think> ### Oracle左连接是否会显示满足查询条件的结果? 在Oracle中,**左连接(LEFT JOIN)会保留左表的所有行**,无论是否满足连接条件或查询条件。具体行为取决于查询条件的位置: #### 1. 当条件在`ON`子句中时 ✅ ```sql SELECT p.Name, a.City FROM Person p LEFT JOIN Address a ON p.AddressID = a.AddressID -- 连接条件 AND a.City = 'New York' -- 查询条件在ON中 ``` - **结果**:左表(Person)所有行都显示 - 右表(Address)满足条件的显示具体值 - 右表满足条件的显示`NULL`(会过滤左表行)[^1] #### 2. 当条件在`WHERE`子句中时 ⚠️ ```sql SELECT p.Name, a.City FROM Person p LEFT JOIN Address a ON p.AddressID = a.AddressID WHERE a.City = 'New York' -- 查询条件在WHERE中 ``` - **结果**:左表满足条件的行会被过滤掉 - 此时左连接退化为内连接(INNER JOIN) --- ### 关键结论 | 条件位置 | 左表是否显示 | 右表匹配时 | 实际效果 | |----------|----------------|--------------|----------| | `ON`子句 | ✅ 是 | 显示NULL | 真正左连接 | | `WHERE`子句 | ❌ 否 | 被过滤 | 退化为内连接 | > **本质区别**: > - `ON`子句条件在**连接时过滤右表**,影响左表 > - `WHERE`子句条件在**连接后过滤最终结果**,会影响左表[^1] --- ### 示例说明 假设数据: ```markdown | Person | Address | |----------------|------------------| | Alice (ID:1) | NY (ID:1) | | Bob (ID:2) | LA (ID:2) | | Carol (ID:3) | (无地址) | ``` ▶️ 查询1(条件在ON): ```sql SELECT p.Name, a.City FROM Person p LEFT JOIN Address a ON p.AddressID = a.AddressID AND a.City = 'NY' -- 只匹配NY地址 ``` 结果: ``` Alice | NY -- 匹配成功 Bob | NULL -- 地址不是NY Carol | NULL -- 无地址 ``` ▶️ 查询2(条件在WHERE): ```sql ... -- 同上连接 WHERE a.City = 'NY' ``` 结果: ``` Alice | NY -- 仅剩完匹配的行 ``` --- ### 最佳实践 需要保留左表所有行时: 1. 将**连接条件**放在`ON`子句 2. 将**右表过滤条件**也放在`ON`子句 3. **左表过滤条件**放在`WHERE`子句 ```sql SELECT p.Name, a.City FROM Person p LEFT JOIN Address a ON p.AddressID = a.AddressID -- 连接条件 AND a.City IN ('NY','LA') -- 右表过滤条件 WHERE p.Age > 18 -- 左表过滤条件 ```
评论 3
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值