栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

根据多个条件从表中删除重复项并保留到其他表

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

根据多个条件从表中删除重复项并保留到其他表

幸运的是,您正在运行PostgreSQL。

DISTINCT ON
应该使这相对容易:

由于您将删除大多数行(约90%重复),并且表很可能很容易放入RAM,因此我选择了以下方法:

  1. SELECt
    将尚存的行放入临时表中。
  2. 重新路由引用列。
  3. DELETE
    基表中的所有行。
  4. 重新
    INSERT
    幸存者。

蒸馏剩余的行

CREATE TEMP TABLE tmp ASSELECT DISTINCT ON (login_name, password) *FROM  (   SELECt DISTINCT ON (email) *   FROM   taccounts   ORDER  BY email, last_login DESC   ) subORDER  BY login_name, password, last_login DESC;

有关更多

DISTINCT ON

  • 在每个GROUP BY组中选择第一行?

要删除两个不同条件的重复项,我只使用一个子查询,一个接一个地应用这两个规则。第一步是使用最新的保留帐户

last_login
,因此这是“可序列化的”。

检查结果并测试合理性。

SELECt * FROM tmp;

在会话结束时会自动删除一个临时表。在pgAdmin(您似乎正在使用)中,会话一直存在,只要您在其中创建了临时表的编辑器窗口中打开即可。

替代查询以更新“重复项”的定义

SELECt *FROM   taccounts tWHERe  NOT EXISTS (   SELECt 1   FROM   taccounts t1   WHERe (NULLIF(t1.email, '') = t.email OR (NULLIF(t1.login_name, ''), NULLIF(t1.password, ''))         = (t.login_name, t.password)         )   AND   (t1.last_login, t1.account_id) > (t.last_login, t.account_id)   );

这不会在任何“重复”列

NULL
中将字符串(
''
)视为空白或将其视为空。

行表达式

(t1.last_login,t1.account_id)
考虑了两个重复可能共享相同的可能性
last_login
account_id
在这种情况下,我会选择更大的一个-这是独特的,因为它是PK。

如何识别所有传入的FK

SELECt c.confrelid::regclass::text AS referenced_table      ,c.conname AS fk_name      ,pg_get_constraintdef(c.oid) AS fk_definitionFROM   pg_attribute a JOIN   pg_constraint c ON (c.conrelid, c.conkey[1]) = (a.attrelid, a.attnum)WHERe  c.confrelid = 'taccounts '::regclass   -- (schema-qualified) table nameAND    c.contype  = 'f'ORDER  BY 1, contype DESC;

或者,您可以

Dependents
在选择pgAdmin的对象浏览器的右侧窗口中检查骑手
taccounts

重新路由到新的母版

如果你有表引用

taccounts
传入的 外键
taccounts
),你将要更新所有这些领域, 之前 你删除受骗者。
将它们全部重新路由到新的主行:

UPDATe referencing_tbl rSET    referencing_column = tmp.reference_columnFROM   tmpJOIN   taccounts t1 USING (email)WHERe  r.referencing_column = t1.referencing_columnAND    referencing_column IS DISTINCT FROM tmp.reference_column;UPDATe referencing_tbl rSET    referencing_column = tmp.reference_columnFROM   tmpJOIN   taccounts t2 USING (login_name, password)WHERe  r.referencing_column = t1.referencing_columnAND    referencing_column IS DISTINCT FROM tmp.reference_column;

进去杀人

现在,这些骗子不再有链接。进去杀人。

ALTER TABLE taccounts DISABLE TRIGGER ALL;DELETe FROM taccounts;VACUUM taccounts;INSERT INTO taccountsSELECt * FROM tmp;ALTER TABLE taccounts ENABLE TRIGGER ALL;

我在操作过程中禁用了所有触发器。这样可以避免在操作过程中检查参照完整性。重新激活触发器后,一切都应该正常。我们已经处理了上面所有 传入的
FK。由于您没有并发访问权限并且所有值以前都在那里,因此保证 传出 FK声音良好。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/407504.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号