比较 SQL Oracle 中 2 个表的供应商

compare suppliers from 2 tables in SQL Oracle

我有 2 table

在两个 table 中都是有物品的供应商。在 table supplier_with_awards 中是可以交付项目的供应商。一件商品可能有多个供应商。在 table suppliers_with_incomming_goods 中是实际供应物品的供应商。存在非中标供应商供货情况

案例一 我需要检查商品是否在两个 table 中,并且只选择那些供应商不同的商品

案例2 与案例 1 相同,但也选择未获奖的供应商。

我的数据

CREATE TABLE suppliers_with_awards ( supplier, item ) AS
SELECT 'supplier1', 'item1'         FROM DUAL UNION ALL
SELECT 'supplier2', 'item1'         FROM DUAL UNION ALL
SELECT 'supplier3', 'item2'         FROM DUAL UNION ALL
SELECT 'supplier4', 'item3'        FROM DUAL ;

CREATE TABLE suppliers_with_incoming_goods ( supplier, item ) AS
SELECT 'supplier1', 'item1'         FROM DUAL UNION ALL
SELECT 'supplier2', 'item1'         FROM DUAL UNION ALL
SELECT 'supplier5', 'item2'         FROM DUAL UNION ALL
SELECT 'supplier6', 'item4'        FROM DUAL ; 

通过简单的连接,我们得到了 item1 不必要的组合 supplier1-supplier2,反之亦然,但实际上 supplier1 获得了奖励并且 supplier1 交付了,supplier2 也是如此。所以我使用 row_number 来排除这种交叉组合,如果你有更好的解决方案让我知道。

with award as (
select supplier, item, row_number() over (partition by item order by supplier) r
from suppliers_with_awards
),
goods as (
select supplier, item, row_number() over (partition by item order by supplier) r
from suppliers_with_incoming_goods
)
select a.supplier,a.item,g.supplier from award a join goods g on a.item=g.item and  a.r=g.r and a.supplier<>g.supplier;

SUPPLIER    ITEM    SUPPLIER
supplier3   item2   supplier5

此查询找到了 item2,因为我想要的供应商不同(案例 1)。同样,如果有更好的解决方案,请.... 但我需要以某种方式让未获奖的供应商 6 也获得 item4(案例 2)

谢谢

当前查询可能不会 return 插入不同值的所有结果,例如 supplier7supplier8 for item1 插入到 table suppliers_with_awards。我不建议在这种情况下使用分析函数,而是您可以将查询转换为以下包含 NOT EXISTS 的查询。并使用 UNION ALL,因为您可能需要 return 两个以上的 supplier 应该已经将每个唯一的单独列为单独的一行

--# Case 1
WITH item_supplier AS
(
 SELECT g.item AS item,
        a.supplier AS supplier_a,g.supplier AS supplier_g
   FROM suppliers_with_awards a
   JOIN suppliers_with_incoming_goods g
     ON a.item = g.item
)
SELECT DISTINCT item, supplier_a AS supplier
  FROM item_supplier i
 WHERE NOT EXISTS ( SELECT 0 
                      FROM item_supplier 
                     WHERE supplier_g = i.supplier_a)         
UNION ALL
SELECT DISTINCT item, supplier_g
  FROM item_supplier i
 WHERE NOT EXISTS ( SELECT 0 
                      FROM item_supplier 
                     WHERE supplier_a = i.supplier_g)  

对于第二种情况只需将INNER JOIN转换为RIGHT or FULL JOIN,并在主查询中过滤掉itemsupplierNULL值比如

--# Case 2
WITH item_supplier AS
(
 SELECT g.item AS item,
        a.supplier AS supplier_a,g.supplier AS supplier_g
   FROM suppliers_with_awards a
  RIGHT JOIN suppliers_with_incoming_goods g
     ON a.item = g.item       
), its AS
(
SELECT DISTINCT item, supplier_a as supplier
  FROM item_supplier i
 WHERE NOT EXISTS ( SELECT 0 
                      FROM item_supplier 
                     WHERE supplier_g = i.supplier_a)         
UNION ALL
SELECT DISTINCT item, supplier_g
  FROM item_supplier i
 WHERE NOT EXISTS ( SELECT 0 
                      FROM item_supplier 
                     WHERE supplier_a = i.supplier_g) 
)
SELECT *
  FROM its                      
 WHERE item IS NOT NULL 
   AND supplier IS NOT NULL 

Demo