Oracle - 具有连接条件的外部连接

Posted

技术标签:

【中文标题】Oracle - 具有连接条件的外部连接【英文标题】:Oracle - Outer Join with join condition 【发布时间】:2020-06-26 16:47:54 【问题描述】:

我有一个场景,我有两个表

订购

ORDER_NO
LOCATION
ITEM
QTY_RECEIVED

发货

ORDER_NO
LOCATION
ITEM
QTY_RECEIVED

在某些情况下,ORDER 表有记录但 SHIPMENT 表没有记录

我想要 ORDER 表中数量不等于 SHIPMENT 表中的数量的所有行,这将包括 ORDER 中但不在装运中的行。

我试过这样做:

SELECT 
    order_no, item, location, SUM(NVL(QTY_RECEIVED, 0)) 
FROM
    ORDERS ol                     
GROUP BY 
    ORDER_NO, ITEM, LOCATION
HAVING 
    SUM (NVL(ol.QTY_RECEIVED,0)) <>      

    (SELECT SUM(NVL(sk.QTY_RECEIVED, 0))
     FROM shipment s
     WHERE s.order_no = ol.order_no
       AND s.item (+)= ol.item
       AND s.location (+) = ol.location
     GROUP BY s.order_no, s.item, s.location);

但它没有给出正确的结果。

我应该怎么做?

【问题讨论】:

【参考方案1】:

即使对于 SHIPMENT 表的不存在值,您也需要 LEFT JOIN 才能返回结果:

SELECT ol.order_no, ol.item, ol.location, 
       SUM(NVL(ol.QTY_RECEIVED, 0)) AS "Total Quantity Of Orders",
       SUM (NVL(s.QTY_RECEIVED,0))  AS "Total Quantity Of Shpm." 
  FROM orders ol 
  LEFT JOIN shipment s  
    ON s.order_no = ol.order_no
   AND s.item = ol.item
   AND s.location = ol.location
 GROUP BY ol.order_no, ol.item, ol.location
HAVING SUM (NVL(ol.QTY_RECEIVED,0)) <> SUM (NVL(s.QTY_RECEIVED,0)) 

【讨论】:

【参考方案2】:

在我看来,一个订单可以为同一个商品多次发货。如果是这种情况,您需要一种不同的方法:

select order_no, location, item, sum(o_qty), sum(s_qty)
from ((select order_no, location, item, qty_received as o_qty, 0 as s_qty
       from orders
      ) union all
      (select order_no, location, item, 0 as o_qty, qty_received as s_qty
       from shipment
      )
     ) os
group by order_no, location, item
having sum(o_qty) <> sum(s_qty);

【讨论】:

以上是关于Oracle - 具有连接条件的外部连接的主要内容,如果未能解决你的问题,请参考以下文章

Oracle-表连接

Oracle-表连接

Oracle多表连接查询Join

Oracle 右外连接

Oracle查询转换之连接谓词推入

为啥当缺少连接字段之一时,HIVE 中的完全外部连接会给出奇怪的结果?