甲骨文左联接
Posted
技术标签:
【中文标题】甲骨文左联接【英文标题】:Oracle left join 【发布时间】:2014-06-02 11:57:46 【问题描述】:我有两张桌子 A1,A2 A1(主键 ID):
| ID | NAME |
|-------|---------|
| 1 | Cat1 |
| 2 | Cat2 |
| 3 | Cat3 |
| 4 | Cat4 |
| 5 | Cat5 |
和A2(主键ID,外键A1_ID=A1.ID)
| ID | NAME | A1_ID | TYPE |
|-------|---------|--------|--------|
| 1 | Sub1 | 1 | L |
| 2 | Sub2 | 2 | F |
| 3 | Sub3 | 3 | V |
| 4 | Sub4 | 4 | L |
| 5 | Sub5 | 4 | V |
| 6 | Sub6 | 5 | |
我正在尝试从 A2.Type 为 L 或 F 或 null 的两个表中获取所有结果
这是我目前所拥有的:
select a.*, b.*
from a1 a
left join a2 b
on a.id=b.a1_id
where (b.type='L'
or b.type='F'
or b.type is null)
返回:
| ID | NAME | ID | NAME | A1_ID | TYPE |
|-------|---------|--------|--------|--------|--------|
| 1 | Cat1 | 1 | Sub1 | 1 | L |
| 2 | Cat2 | 2 | Sub2 | 2 | F |
| 4 | Cat4 | 4 | Sub4 | 4 | L |
| 5 | Cat5 | 6 | Sub6 | 5 | |
但我正在寻找一个查询,它将排除 A1.ID = 4 的行,因为具有相同的 A1_ID 有一行 TYPE=V
| ID | NAME | ID | NAME | A1_ID | TYPE |
|-------|---------|--------|--------|--------|--------|
| 1 | Cat1 | 1 | Sub1 | 1 | L |
| 2 | Cat2 | 2 | Sub2 | 2 | F |
| 5 | Cat5 | 6 | Sub6 | 5 | |
有什么想法吗?
【问题讨论】:
基于 A1_ID 的左连接到左连接,其中类型为 v 如果记录存在则排除该行。 你试过NATURAL JOIN
吗?
【参考方案1】:
您可以使用not exists
:
select a.*, b.*
from a1 a left join
a2 b
on a.id = b.a1_id
where (b.type = 'L' or b.type='F' or b.type is null) and
not exists (select 1 from a2 where a2.id = a.id and a2.type = 'V');
您的原始查询并没有完全按照您的文字所说的那样做。这似乎是您所描述的:
select a.*, b.*
from a1 a join
a2 b
on a.id = b.a1_id and
(b.type = 'L' or b.type='F' or b.type is null)
where not exists (select 1 from a2 where a2.id = a.id and a2.type = 'V');
即where
子句中的条件移动到on
子句中,将join改为inner join。不同之处在于a2
中对于给定的id
没有匹配项。您的版本将返回该行。此版本会将其过滤掉。
【讨论】:
【参考方案2】:select a.*, b.*
from a1 a
left join a2 b
on a.id=b.a1_id
left join a2 c
on c.a1_ID = b.a1_ID AND c.type = 'V'
where (b.type='L'
or b.type='F'
or b.type is null)
and c.type is null
这是一种方式。如果您只需要考虑 v 这应该是有效的。但是,如果您需要根据其他标准进行调整,可能会有更好的方法。
本质上,这会将您当前的结果与另一组仅包含记录类型“V”的 a2 进行比较。如果找到任何匹配项,则将其从结果中排除。
【讨论】:
以上是关于甲骨文左联接的主要内容,如果未能解决你的问题,请参考以下文章