甲骨文:加入TOP 1纪录

时间:2015-09-03 15:08:07

标签: oracle join oracle11g oracle10g oracle-sqldeveloper

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

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

所以这是我的2张桌子。 “项目”包含项目名称&该项目的批次#。然后我需要进入我们的“Item_Inventory”表来查找该商品当前是否有库存(如果该商品当前不在此表中,则该商品没有库存)。

===========================
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

这是我要返回的内容(注意项目“ALC-6697-MI”被排除,因为它在Item_Inventory表中没有当前库存):

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  

我如何加入这两个表但是保持一对一的关系?

由于

3 个答案:

答案 0 :(得分:2)

选项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
)

答案 1 :(得分:2)

您可以使用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子句来解决相关问题。

答案 2 :(得分:0)

这是最容易的(可能,但你必须测试你的数据)最快才能在加入两个表之前做一个明确的,例如。类似的东西:

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);

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

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);