left outer加入缺失的记录

时间:2016-09-21 19:31:50

标签: sql oracle11g

我正在尝试列出PartsOnHand中缺少的记录。如果我的库存表列出了一个项目并且它与我的PartsOnHand无关,我想列出每个记录缺少哪些项目。

以下是我尝试使用的查询:

select * 
from inventory i
left outer join PartsOnHand ph on  i.InName = ph.InName 

我的表格结构如下:

清单:

InName
-----------
Wrench
Hammer 
Pen

PartsOnHand:

id    Inname
------------------
505   Hammer 
505   Wrench
501   Wrench
501   Hammer 

期望的结果:

505   Pen
501   Pen

示例数据:

Select *
    FROM (
with inventory as (
    select 'Wrench' as InName from dual
    union 
    select 'Hammer' from dual
    union 
    select 'Pen' from dual

    ), partsonhand as (
    select '505' as id, 'Wrench' InName  from dual
    union  
    select '505' as id, 'Hammer' InName from dual
    union 
    select '501' as id, 'Wrench' InName from dual
    union 
    select '501' as id, 'Hammer' InName from dual
    )
    select * 
    from inventory i
    left outer join PartsOnHand ph on  i.InName = ph.InName 

    )

3 个答案:

答案 0 :(得分:0)

您有一个额外的表ALL_ID,其中包含列ID(主键和PartsOnHand中的列ID指向它),这将是正确的设置;或者您希望从表PartsOnHand中读取ID。我会假设前者;如果它是后者,可以通过从PartsOnHand中选择不同的id来将ALL_ID创建为子查询

select id, inname
from   all_id cross join inventory
where  (id, inname) not in (select id, inname from partsonhand)
;

这假设PartsOnHand中没有NULLS(不应该是 - 否则你有数据问题)。

答案 1 :(得分:0)

您可以通过Id创建InNameCROSS JOIN的所有不同可能组合并对该结果执行RIGHT JOIN来执行此操作:

Select  L.*
From    PartsOnHand P
Right Join
(
    Select  Id, InName
    From    Inventory   I
    Cross Join
    (
        Select  Distinct Id
        From    PartsOnHand P
    ) X
) L On  L.id = P.id
    And L.InName = P.InName
Where   P.id Is Null
  

结果:

Id  InName
501 Pen
505 Pen

答案 2 :(得分:0)

似乎奇怪的是将相同的ID分配给不同的名称...(我怎么知道Pen的ID是505和501?)但是这会在例子中提供所需的结果:

with inventory as (
select 'Wrench' as InName from dual
union 
select 'Hammer' from dual
union 
select 'Pen' from dual

), partsonhand as (
select '505' as id, 'Wrench' InName  from dual
union  
select '501' as id, 'Hammer' InName from dual
union 
select '505' as id, 'Wrench' InName from dual
union 
select '501' as id, 'Hammer' InName from dual
)
select C.ID, I.InName 
from inventory i
LEFT join partsonhand P
 on I.Inname = P.InName
cross join (Select distinct ID from partsonHand) C
Where P.ID is null
order by ID Desc;

enter image description here