比较 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 插入不同值的所有结果,例如 supplier7
和 supplier8
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
,并在主查询中过滤掉item
和supplier
的NULL
值比如
--# 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
我有 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 插入不同值的所有结果,例如 supplier7
和 supplier8
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
,并在主查询中过滤掉item
和supplier
的NULL
值比如
--# 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