识别 2 个表中的不同行

Posted

技术标签:

【中文标题】识别 2 个表中的不同行【英文标题】:Identifying distinct rows across 2 tables 【发布时间】:2012-09-11 02:31:16 【问题描述】:

假设我有两个结构相同的表,分别称为 A 和 B。此问题关注的唯一列是 product_type、price 和 volume。

product_type 和 price 的每个组合可以在每个表中以不同的数量重复多次。我正在尝试在一个表中查找具有不同 TOTAL 卷的组合实例。

这将包括表 A 中的组合未在表 B 中表示的情况,反之亦然。

====================

例子:

表 A:

ID   Product_type   Price  Volume
---  ------------   -----  ------
1         X           $1     10
2         X           $1     11
3         Z           $2     10

表 B:

ID   Product_type   Price  Volume
--   -------------  -----  -------
1         X           $1     21
2         Y           $1     5
3         Z           $2     7
4         Z           $2     4

请注意,表 A 中 X @ $1 的交易量总和为 21,与表 B 匹配。 Y @ $1 出现在表 B 中,但不在 A 中。 Z @ $2 出现在两个表中,但它们的体积总和不同。我希望查询返回违反规则的每个产品类型和价格组合(即 Y @ $1 和 Z @ $2)。

我尝试过使用 GROUP、UNION、DISTINCT、子查询和上述各种组合,但似乎无法弄清楚。

【问题讨论】:

【参考方案1】:

我相信以下是您正在寻找的内容。我为奇怪的 where/not 语法道歉,concat 中的子查询似乎是最易读的方法。

(
SELECT
  "TableA",
  TA.*

FROM TableA AS TA

WHERE CONCAT(product_type, price,
             (SELECT SUM(volume) FROM TableA WHERE product_type = TA.product_type AND price = TA.price))

NOT IN (SELECT CONCAT(product_type, price, SUM(volume)) FROM TableB GROUP BY product_type, price)
)

UNION

(
SELECT
  "TableB",
  TB.*

FROM TableB AS TB

WHERE CONCAT(product_type, price,
             (SELECT SUM(volume) FROM TableB WHERE product_type = TB.product_type AND price = TB.price))

NOT IN (SELECT CONCAT(product_type, price, SUM(volume)) FROM TableA GROUP BY product_type, price)
)

#ORDER BY <column>

输出:

TableA  ID  Product_type  Price  Volume
TableA  3   Z             $2     10
TableB  2   Y             $1     5
TableB  3   Z             $2     7
TableB  4   Z             $2     4

【讨论】:

【参考方案2】:
create table a (ID integer, Product_type char(1), Price float, Volume integer);
create table b (ID integer, Product_type char(1), Price float, Volume integer);

insert into a (ID, Product_type, Price, Volume) values
(1, 'X', 1, 10),
(2, 'X', 1, 11),
(3, 'Z', 2, 10)
;
insert into b (ID, Product_type, Price, Volume) values
(1, 'X', 1, 21),
(2, 'Y', 1, 5),
(3, 'Z', 2, 7),
(4, 'Z', 2, 4)
;

select 
    a.Product_type as Product_type_a,
    a.Price as Price_a,
    a.Volume as Volume_a,
    b.Product_type as Product_type_b,
    b.Price as Price_b,
    b.Volume as Volume_b
from (
        select Product_type, Price, sum(Volume) as Volume
        from a
        group by Product_type, Price
    ) a
    full outer join (
        select Product_type, Price, sum(Volume) as Volume
        from b
        group by Product_type, Price
    ) b on a.Product_type = b.Product_type and a.Price = b.Price
where 
    a.Volume != b.Volume
    or a.Volume is null or b.Volume is null
;
 product_type_a | price_a | volume_a | product_type_b | price_b | volume_b 
----------------+---------+----------+----------------+---------+----------
 Z              |       2 |       10 | Z              |       2 |       11
                |         |          | Y              |       1 |        5

【讨论】:

谢谢。这很好用,只需要修改它以合并两个连接,因为 mysql 不支持完全外部连接。 @user1681248 不知道。我在 postgresql 中对其进行了测试,因为这是我现在可以访问的。【参考方案3】:

这似乎是work for me:

SELECT a.Product_type, a.volume, b.Product_type, b.volume
FROM
  (SELECT Product_type, SUM(volume) AS volume
  FROM tbl1 GROUP BY Product_type) a
INNER JOIN
  (SELECT Product_type, SUM(volume) AS volume
  FROM tbl2 GROUP BY Product_type) b ON b.Product_type = a.Product_type
WHERE a.volume <> b.volume

结果

| PRODUCT_TYPE |音量 | PRODUCT_TYPE |音量 | -------------------------------------------------- | Z | 10 | Z | 11 |

【讨论】:

以上是关于识别 2 个表中的不同行的主要内容,如果未能解决你的问题,请参考以下文章

在一个表中的不同行和不同列中查找相同的值SQL

如何在准备好的语句php中的不同行中插入多条记录

SQL计算GBQ中表中的不同行数

C# - 以编程方式识别 2 个表之间的关系类型

SQL JOIN - 选择非不同行的值

如何识别 Chrome DevTools 或 Firefox 中的不安全内容?