Oracle离开了加入

时间:2014-06-02 11:57:46

标签: oracle oracle11g

我有两张桌子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    |        |

有什么想法吗?

2 个答案:

答案 0 :(得分: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子句,并且连接被更改为内连接。不同之处在于,对于给定的a2id中没有匹配项。您的版本将返回该行。此版本将过滤掉它。

答案 1 :(得分:0)

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