有可能在表中,某些具有重复值的字段需要使其保持唯一。
以及如何处理重复的值而不将它们全部消除?
是否可以只保留最新的?
ctid系统列
每个表都有一些系统隐式定义的列,它们的名称是保留的。
目前系统列有:tableoid、xmin、cmin、xmax、cmax和ctid。每个都有来自它们所属表的元数据。
ctid 系统列旨在存储行的物理位置的版本。如果行
更新 (UPDATE) 或表经历 VACUUM FULL,则此版本可能会更改。ctid
的数据类型是 tid,表示元组标识符(或行标识符),它是一对(块号,块内的元组索引)
,用于标识行在表中的物理位置。
此列在表中始终具有其唯一值,因此当存在具有重复值的行时,可以将其用作消除它们的标准。
测试表创建:
CREATE TABLE tb_test_ctid ( col1 int, col2 text);
复制
插入一些数据:
INSERT INTO tb_test_ctid VALUES (1, 'foo'), (2, 'bar'), (3, 'baz');
复制
检查当前行:
SELECT ctid, * FROM tb_test_ctid;
复制
更新一行:
UPDATE tb_test_ctid SET col2 = 'spam' WHERE col1 = 1; UPDATE tb_test_ctid SET col2 = 'eggs' WHERE col1 = 1 RETURNING ctid;
复制
再次检查表:
SELECT ctid, * FROM tb_test_ctid;
复制
使用 ctid 消除重复值
想象一下,一个表在一个字段中具有重复的值,并且该字段稍后被决定使其唯一。
请记住,PRIMARY KEY 字段也是唯一的。
好的,决定删除该字段中的重复值。
现在有必要建立一个标准来决定这些重复值将保留。
在以下情况下,标准是最新的行,即具有最高 ctid 值的行。
New test table creation:
CREATE TABLE tb_foo( id_ int, --This field will be the primary key in the future! letter char(1) );
复制
插入一些数据
INSERT INTO tb_foo (id_, letter) SELECT generate_series(1, 10), 'a';
复制
查表:
SELECT id_, letter FROM tb_foo;
复制
插入一些数据
INSERT INTO tb_foo (id_, letter) SELECT generate_series(1, 3), 'b';
复制
找出重复值:
WITH t AS ( SELECT id_, count(id_) OVER (PARTITION BY id_) AS count_id, -- Count ctid, max(ctid) OVER (PARTITION BY id_) AS max_ctid -- Most current ctid FROM tb_foo ) SELECT t.id_, t.max_ctid FROM t WHERE t.count_id > 1 -- Filters which values repeat GROUP by id_, max_ctid;
复制
WITH t1 AS ( SELECT id_, count(id_) OVER (PARTITION BY id_) AS count_id, ctid, max(ctid) OVER (PARTITION BY id_) AS max_ctid FROM tb_foo ), t2 AS ( -- Virtual table that filters repeated values that will remain SELECT t1.id_, t1.max_ctid FROM t1 WHERE t1.count_id > 1 GROUP by t1.id_, t1.max_ctid) DELETE -- DELETE with JOIN FROM tb_foo AS f USING t2 WHERE f.id_ = t2.id_ AND -- tb_foo has id_ equal to t2 (repeated values) f.ctid < t2.max_ctid; -- ctid is less than the maximum (most current)
复制
加上主键
ALTER TABLE tb_foo ADD CONSTRAINT tb_foo_pkey PRIMARY KEY (id_);
复制
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
反省本质上是自我认知的一个过程。一个人只有清楚地认识自己,才知道如何改进和提高。
2年前

评论