You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL中如何删除name列存在重复值的冗余行及解决row_num列不存在报错

解决PostgreSQL删除重复行的报错问题

嘿,你遇到的问题其实是两个小细节导致的:一是混用了SQL Server的语法,二是没注意PostgreSQL对CTE删除的限制,我来一步步帮你解决:

报错的直接原因

你写的row_num = row_number()是SQL Server里定义列别名的写法,但PostgreSQL里必须用AS关键字来指定别名,所以这行应该改成:

row_number() over (partition by name order by ID) AS row_num

第二个问题:PostgreSQL不能直接删除CTE中的行

即使修正了别名,你原来的delete from cte写法在PostgreSQL里也不生效——PostgreSQL不支持直接从CTE执行删除操作,你需要通过CTE关联原表来定位要删除的行。

正确的SQL写法

这里提供两种可行的方案,都能实现你要的“每个name只保留唯一行(保留id最小的那一条)”的需求:

方案一:CTE + DELETE USING(清晰直观)

WITH cte AS (
    SELECT id,
           row_number() OVER (PARTITION BY name ORDER BY id) AS row_num
    FROM public.tentacle_ticker
)
DELETE FROM public.tentacle_ticker
USING cte
WHERE public.tentacle_ticker.id = cte.id
AND cte.row_num > 1;

这个逻辑是:先给每个name分组里的行按id排序编号,然后通过USING关联原表,删除编号大于1的行(也就是保留每个分组里最小编号的行)。

方案二:WHERE EXISTS(更简洁)

如果不需要CTE,也可以用子查询直接实现:

DELETE FROM public.tentacle_ticker t1
WHERE EXISTS (
    SELECT 1
    FROM public.tentacle_ticker t2
    WHERE t2.name = t1.name
    AND t2.id < t1.id
);

这个写法的逻辑是:删除那些存在同name但id更小的行,最终每个name只会保留id最小的那一行,效果和方案一完全一致。

执行任意一种方案后,你的表就会得到期望的结果:

id | name | symbol
1 | Two | Three
3 | Three | Three

内容的提问来源于stack exchange,提问作者JSRB

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 17:47:40