甲骨文左联接

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 进行比较。如果找到任何匹配项,则将其从结果中排除。

【讨论】:

以上是关于甲骨文左联接的主要内容,如果未能解决你的问题,请参考以下文章

甲骨文 maf 和甲骨文 af

甲骨文扩展客户云产品组合 覆盖PaaSSaaS和大数据

甲骨文要拿 JavaScript 开刀了?

呵呵,甲骨文:Android 是破坏开源的罪犯

谷歌大战甲骨文,没想到这么污!

导致甲骨文全球性裁员的原因有哪些?