【问题标题】:Find duplicates in database and rename one在数据库中查找重复项并重命名一个
【发布时间】:2011-03-23 12:07:08
【问题描述】:

我在 Postgres 中有一张桌子,里面塞满了文章。这些文章有一个与之关联的 url slug,用于将它们显示为 example.com/pretty_name 而不是 example.com\2343。

不幸的是,当我刚开始时,我对 url 实施了唯一约束,但忽略了不区分大小写的情况,我想纠正这个错误并开始要求 url 是唯一的,不考虑大小写。

作为第一步,我需要修复数据库中已经存在的所有重复 url。 如何在不区分大小写的情况下在表格中搜索具有重复 url 的行,并保留一行,而对于其余重复行,在末尾附加“_2”之类的内容? p>

这特别棘手,因为我不能 100% 确定网址不会重复超过一次。即,我可能在一个 url 上有 3 个重复项,在这种情况下,理想情况下,我希望第一个是 pretty_name,第二个是 pretty_name_2,第三个是 pretty_name_3。

【问题讨论】:

  • 有一些架构是提供高质量答案所必需的。
  • 架构非常简单。有一个表格文章,它有一个列 url。您还有什么想知道的相关信息吗?
  • 大声笑,在你最后一个问题之后,我有一半预料到这个问题 - 你的文章表上有一个 id 列吗?

标签: postgresql duplicates unique


【解决方案1】:

如果你的桌子上有某种唯一的 id:

UPDATE articles a1 set url = a1.url||'_2' 
WHERE a1.id not in (select max(a2.id) from articles a2 group by lower(a2.url));

如果您没有唯一 ID:

UPDATE articles a1 set url = a1.url||'_2' 
WHERE a1.ctid not in (select max(a2.ctid) from articles a2 group by lower(a2.url));

【讨论】:

  • 您能解释一下这些语句的工作原理吗?这是否是为了更新 not 具有最大 ID 但与另一条记录共享不区分大小写 URL 的 articles 记录?如果是这样,如果有不止一场比赛会发生什么?它是否会转换 all 的 URL 但具有最大 ID 的记录?
  • 为每组不区分大小写的 url 更新不是最大 id 的每一行。是的,它将转换除具有最大 id 的记录之外的所有 URL。
  • 再次感谢!我自己的个人数据库救星。为了捕获多个重复项,也许我会一遍又一遍地运行同一件事,同时增加数字,直到不再有重复项。在以后的运行中,我想我需要设计一种方法来告诉数据库首先切断 _2 并用 _3 替换它。
  • 您可以通过将 '2' 替换为 ''||round(random()*100) 来大大减少这些运行次数。它并不完美,但如果只有一些变化,你不太可能得到重复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-24
  • 2018-04-02
  • 2023-03-23
  • 1970-01-01
  • 1970-01-01
  • 2019-01-05
相关资源
最近更新 更多