我有一个包含 60 列的 company
表。目标是创建一个工具来查找、比较和消除此表中的重复项。
示例:我发现 2 家公司可能相同,但我需要知道这两行之间哪些值(列)不同才能继续。
我认为可以逐列 x 60 进行比较,但我正在寻找更简单、更通用的解决方案。
类似于:
SELECT * FROM company where co_id=22
SHOW DIFFERENCE
SELECT * FROM company where co_id=33
结果应该是不同的列名。
最佳答案
为此,您可以使用行的中间键/值表示,使用 JSON 函数或使用 hstore
扩展(现在仅具有历史意义)。 JSON 内置于每个合理的最新版本的 PostgreSQL 中,而 hstore 必须使用 CREATE EXTENSION 安装在数据库中。
演示:
CREATE TABLE table1 (id int primary key, t1 text, t2 text, t3 text);
让我们插入主键不同的两行和另一列 (t3
)。
INSERT INTO table1 VALUES
(1,'foo','bar','baz'),
(2,'foo','bar','biz');
用json解决
首先获取具有原始行号的行的键/值表示,然后我们根据原始行号对行进行配对,然后 过滤掉具有相同“值”列的那些
WITH rowcols AS (
select rn, key, value
from (select row_number() over () as rn,
row_to_json(table1.*) as r from table1) AS s
cross join lateral json_each_text(s.r)
)
select r1.key from rowcols r1 join rowcols r2
on (r1.rn=r2.rn-1 and r1.key = r2.key)
where r1.value <> r2.value;
示例结果:
key ----- id t3
Solution with hstore
SELECT skeys(h1-h2) from
(select hstore(t.*) as h1 from table1 t where id=1) h1
CROSS JOIN
(select hstore(t.*) as h2 from table1 t where id=2) h2;
h1-h2
逐个键地计算差异,skeys()
将结果作为一个集合输出。
结果:
skeys ------- id t3
选择列表可以使用 skeys((h1-h2)-'id'::text)
进行细化,以始终删除 id
作为主键, 显然行之间总是不同的。
关于postgresql - 获取两行之间不同的列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28630354/