我需要区分两个mysql表,并报告对结果子集的更改。
假设我有两张table:
表a:
id name supplier value
-----------------------------------------
1 Alice X 100
2 Bob Y 200
3 Clare Z 300
4 Desmond X 400
表b:
id name supplier value
-----------------------------------------
1 Alice X 150
2 Bob X 200
3 Clare Z 350
4 Desmond X 400
5 Emily X 500
我对涉及供应商x的任何行的更改感兴趣。鉴于上述情况,我想返回:
id 1,因为供应商是x,并且值已更改;
id 2,因为供应商已从y更改为x;
ID5,因为供应商是x,表a中没有对应的行。
我对id 3不感兴趣,因为虽然值已经更改,但是更改不涉及供应商x。我也不感兴趣的id 4,因为没有任何变化。
我可以用 UNION ALL
要计算差异:
SELECT *
FROM
(
SELECT a.id, a.name, a.supplier, a.value, 'a' as tbl
FROM a
UNION ALL
SELECT b.id, b.name, b.supplier, b.value, 'b' as tbl
FROM b
) t
GROUP BY id, name, supplier, value
HAVING COUNT(*) = 1
ORDER BY id
这将返回数据已更改的所有行:
id name supplier value tbl
---------------------------------------------------
1 Alice X 100 a
1 Alice X 150 b
2 Bob Y 200 a
2 Bob X 200 b
3 Clare Z 300 a
3 Clare Z 350 b
5 Emily X 500 b
但是,它还包括我不感兴趣的id 3,因为表a或b中的行都没有supplier x。
最后,我的问题是-如果其中一个不同的行是supplier x,如何返回结果?我当然可以在代码中过滤结果,但是在一个查询中这样做会更好。
4条答案
按热度按时间uajslkp61#
我会用两个
LEFT JOINS
用一个UNION
:首先,加入表
A
到表B
,然后进行反向连接。我不确定是否可以通过表的id连接这些表,因此在本例中,我使用名称作为连接列。
每个连接都包含一个
WHERE
使用cirteria筛选行的子句:“对涉及供应商x的任何行的更改”。这是一把小提琴:http://sqlfiddle.com/#!9/46f213/1号楼
ssm49v7z2#
扩展lldar的答案,您还可以通过对列进行散列,然后查找更改来获得差异。
如果您有许多列,这会很有帮助。理想情况下,从长远来看,您可以编辑这些表,并将哈希添加为“computed/calculated”列。
那就简单了
A.hash <> b.hash
gblwokeq3#
您可以在原始查询中添加一些where子句来检查supplier x,但我想我会采取稍微不同的方法,并使用join:
这将获取已更改但仅与x相关的行。注意,这假设每个表中始终只有一个匹配的id。
4jb9z9bj4#
只使用左连接就可以满足要求