识别 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 个表中的不同行的主要内容,如果未能解决你的问题,请参考以下文章