Pgsql怎样找到表中某个字段值重复的记录并删除冗余记录,只保留一条

发布于:2024-04-11 ⋅ 阅读:(168) ⋅ 点赞:(0)

背景

今天发现某个黄页爬取的数据有部分重复了,原本我用的公司详情页的url进行md5来作为主键做upsert入,但后面在核验数据时发现有些详情url虽是同一间公司的,但路由上有细微差别导致写入了重复的公司数据,所以要想办法清理掉重复的公司;
除了有表id外,我的表里还有一个local_id字段,用于保存页面上的内部id,下面就从这个字段入手进行;

实现方案

第一步首先是看看有多少重复的记录,这个很简单,通过group by local_id就能找到了,如下:

SELECT
	"local_id" 
FROM
	"result".table_name
WHERE
	"sources" = 'xxxx' 
GROUP BY
	"local_id" 
HAVING
	COUNT ( "local_id" ) > 1 
	)

结果数量是91条,这就意味着有91个公司的信息有重复的;

然后我想看看总共有多少条对应的重复公司记录

SELECT
	*,
	ROW_NUMBER ( ) OVER ( PARTITION BY local_id ORDER BY "company_id" ) AS rn 
FROM
	(
	SELECT
		* 
	FROM
		"result".table_name 
	WHERE
		"sources" = 'xxxx' 
		AND "local_id" IN ( SELECT "local_id" FROM "result".table_name WHERE "sources" = 'xxxx' GROUP BY "local_id" HAVING COUNT ( "local_id" ) > 1 ) 
	ORDER BY
	"local_id" 
	) T) 

查询结果是是182条,也就意味着重复的公司记录里,每家公司信息都是重复了1条;

接着下来的问题是怎样实现把多余的删除,只保留一条的目的,这里用到的pgsql的分区功能,他会根据指定字段值给相同的值增加一个编号,以下是我这个场景的示例:

SELECT
	* 
FROM
	(
	SELECT
		*,
		ROW_NUMBER () OVER ( PARTITION BY local_id ORDER BY "company_id" ) AS rn 
	FROM
		(
		SELECT
			* 
		FROM
			"result".table_name
		WHERE
			"sources" = 'xxxx' 
			AND "local_id" IN ( SELECT "local_id" FROM "result".table_name WHERE "sources" = 'xxxx' GROUP BY "local_id" HAVING COUNT ( "local_id" ) > 1 ) 
		ORDER BY
			"local_id" 
		) T 
	) t1 
WHERE
	rn = 2;

通过这条sql,可以把每个local_id重复的记录找出来,删除后就能达到只保留一条记录的目的了,如果重复的记录不只一条,只要把最后的条件改成 >=2 就可以了。

如果本文解决了你的问题,请点赞精神支持一下,这能鼓励我继续做更多的分享,谢谢


网站公告

今日签到

点亮在社区的每一天
去签到