甲骨文:加入TOP 1记录

Oracle: Joining on TOP 1 record

我在这里看到了一些类似问题的答案,但还没有完全正确地实现它。

我想在 2 个 oracle table 之间创建一个应该创建一对一关系的 JOIN。不幸的是,由于我的第二个 table 的设置,它 return 是一对多关系。

这是我的 2 tables。 "Items" 包含项目名称和项目的批号。然后我需要进入我们的 "Item_Inventory" table 以查找该商品当前是否有货(如果该商品当前不在此 table 中,则它没有库存)。

===========================
ITEMS
===========================
Item_No     |   Lot_Num
---------------------------
SHP-705-F   |   X456588R
BAG-DRAWSTR |   Y245899Z
ALC-6697-MI |   A237520P
---------------------------

=======================================================
ITEM_INVENTORY
=======================================================
Item_No     |   Lot_Num    |  BIN_LOC  |  QTY_ONHAND 
-------------------------------------------------------
SHP-705-F   |   X456588R   |   P8541E  |     82      
SHP-705-F   |   X456588R   |   Q8870Q  |     82      
SHP-705-F   |   X456588R   |   U4142B  |     82      
BAG-DRAWSTR |   Y245899Z   |   P5888D  |     15
BAG-DRAWSTR |   Y245899Z   |   R5588Z  |     15
BAG-DRAWSTR |   Y245899Z   |   W8339A  |     15
-------------------------------------------------------

这是我的查询:

SELECT i.Item_No, i.Lot_Num 
FROM ITEMS i
JOIN ITEM_INVENTORY inv ON inv.Item_No = i.Item_No AND inv.Lot_Num = i.Lot_Num

这是我想要的return(注意项目 "ALC-6697-MI" 被排除在外,因为它在 Item_Inventory table 中没有当前库存):

Item_No     |   Lot_Num
---------------------------
SHP-705-F   |   X456588R
BAG-DRAWSTR |   Y245899Z

相反,由于 Item_Inventory.Bin_Loc 字段,我在加入时得到了这个:

Item_No     |   Lot_Num    
-------------------------
SHP-705-F   |   X456588R     
SHP-705-F   |   X456588R      
SHP-705-F   |   X456588R      
BAG-DRAWSTR |   Y245899Z  
BAG-DRAWSTR |   Y245899Z  
BAG-DRAWSTR |   Y245899Z  

我如何加入这 2 个 table 并保持一对一的关系?

谢谢

选项 1:只需在 select 子句中添加 distinct:

select distinct ITEMS.Item_No, ITEMS.Lot_Num
from ... /* the rest of your query*/

选项 2:使用 exists 子句:

select i.Item_No, i.Lot_Num
from ITEMS i
where exists (
    select *
    from ITEM_INVENTORY inv
    where inv.Item_no = i.Item_no and inv.Lot_Num = i.Lot_Num
)

在加入两个 table 之前做一个 distinct 是最简单和最快的(可能,但你必须测试你的数据),例如。类似于:

select *
from   items i
       inner join (select distinct item_no, lot_num from item_inventory) ii on (ii.item_no = i.item_no and ii.lot_num = i.lot_num);

您还可以为清单中项目组的每一行分配一个编号 table,但这可能需要更长的时间。当然,您必须进行测试!例如

select *
from   items i
       inner join (select item_no, lot_num, row_number() over (partition by item_no, lot_num order by bin_loc) rn from item_inventory) ii on (ii.item_no = i.item_no and ii.lot_num = i.lot_num and ii.rn = 1);

您可以使用 in 子句:

select i.Item_No, i.Lot_Num
  from ITEMS i
 where (i.Item_No, i.Lot_Num)
    in (select inv.Item_No, inv.Lot_Num
          from ITEM_INVENTORY inv
         where inv.Item_no = i.Item_no
           and inv.Lot_Num = i.Lot_Num)

上面的子查询可以通过省略 where inv.Item_no = i.Item_no and inv.Lot_Num = i.Lot_Num 子句来关联(如图所示)或不关联。