如何使用重复项的计数更新PostgreSQL表

Jon*_*sco 2 sql postgresql duplicates duplicate-removal sql-update

我在程序中发现了两个错误,它们创建了许多重复值:

  • 创建了'索引'而不是'唯一索引'
  • 复制检查未集成在4个扭曲例程中的一个中

所以我需要进入并清理我的数据库.

第一步是用所有重复值的计数装饰表(接下来我将查看找到第一个值,然后将所有内容迁移)

下面的代码可以工作,我只记得在几年前在同一个表上做了类似的"从选择计数更新",我做了一半的代码.

有没有更好的方法来写这个?

UPDATE 
    shared_link 
SET 
    is_duplicate_of_count = subquery.is_duplicate_of_count 
FROM
    (
        SELECT 
            count(url) AS is_duplicate_of_count 
            , url
        FROM 
            shared_link
        WHERE
            shared_link.url = url
        GROUP BY 
            url
    ) AS subquery
WHERE 
    shared_link.url = subquery.url
;
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 6

通常,除了子查询中无意义(但也无害)的WHERE子句之外,您的查询都很好:

UPDATE shared_link 
SET    is_duplicate_of_count = subquery.is_duplicate_of_count 
FROM  (
    SELECT url
         , count(url) AS is_duplicate_of_count 
    FROM   shared_link
--  WHERE  shared_link.url = url
    GROUP  BY url
    ) AS subquery
WHERE shared_link.url = subquery.url;
Run Code Online (Sandbox Code Playgroud)

注释的子句与

WHERE  shared_link.url = shared_link.url
Run Code Online (Sandbox Code Playgroud)

因此只消除NULL值(因为NULL = NULL不是TRUE),这在您的设置中很可能既不打算也不需要.


除此之外,您只能使用别名和较短的名称进一步缩短代码:

UPDATE shared_link s
SET    ct = u.ct
FROM  (
    SELECT url, count(url) AS ct
    FROM   shared_link
    GROUP  BY 1
    ) AS u
WHERE s.url = u.url;
Run Code Online (Sandbox Code Playgroud)

在PostgreSQL 9.1或更高版本中,您可以在一个带有聚合和窗口函数以及数据修改CTE的 SQL语句中执行整个操作(识别欺骗,合并数据,删除欺骗)- 从而无需另外开始使用列.