postgresql - 获取两行之间不同的列

标签 postgresql postgresql-9.1 duplicates

我有一个包含 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/

相关文章:

python - 如何使用 python Psycopg2 和参数绑定(bind)在 postgres 数组列中插入?

PostgreSQL isset 函数

postgresql - 如何列出表的记录以及通过关系使用了多少的计数器

excel - 如何根据 'n' 是单元格中的数字插入 'n' 行数

python - 从文本文件中删除重复项

sql - 当 SQL 包含变量时在 pgAdmin 中调试 SQL

postgresql - 加入 Postgres BDR 节点使用过时的 DSN

mysql - 数据库设计最佳实践 : Return multiple rows with individual entries, 或具有多个条目的单行?

ruby-on-rails - ruby on rails 无法在本地连接到 postgresql

mysql - 分组后消除某些重复的行