15

我正在使用 postgreSQL 9.1,我想使用此提示从表中删除重复项: https ://stackoverflow.com/a/3822833/2239537

所以,我的查询看起来像这样:

WITH cte
 AS (SELECT ROW_NUMBER() 
 OVER (PARTITION BY code, card_id, parent_id 
     ORDER BY id DESC) RN
     FROM card)
DELETE FROM cte
WHERE RN > 1

但它告诉我

ERROR: relation "cte" does not exist
SQL state: 42P01
Character: 157

但是,此语句工作正常:

WITH cte
 AS (SELECT ROW_NUMBER() 
 OVER (PARTITION BY code, card_id, parent_id 
     ORDER BY id DESC) RN
     FROM merchantcard)
SELECT * FROM cte
WHERE RN > 1

任何想法如何让它工作?谢谢!

4

3 回答 3

35

这是因为 PostgreSQL 中的 CTE 与 SQL Server 中的 CTE 工作方式不同。在 SQL Server 中,CTE 就像一个可更新的视图,因此您可以从中删除或更新它们,而在 PostgreSQL 中则不能。

您可以加入 cte 并删除,例如:

with cte as (
    select
        id,
        row_number() over(partition by code, card_id, parent_id order by id desc) as rn
    from card
)
delete
from card
where id in (select id from cte where rn > 1)

另一方面,您可以在 PostgreSQL 的 CTE 中编写 DDL 语句(请参阅文档),这可能非常方便。例如,您可以从中删除所有行card,然后仅插入 row_number = 1 的行:

with cte1 as (
    delete
    from card
    returning *
), cte2 as (
    select
        row_number() over(partition by code, card_id, parent_id order by id desc) as rn,
        *
    from cte1
)
insert into card
select <columns here>
from cte2
where rn = 1
于 2013-08-26T07:45:56.067 回答
9

我知道,您在问如何使用 WITH 语句解决问题,并且已经得到了很好的答案。但我建议在您链接的同一问题中寻找替代方案。

这个如何?

DELETE FROM card
WHERE id NOT IN (
  SELECT MIN(id) FROM card
  GROUP BY code, card_id, parent_id 
);
于 2013-10-24T07:38:40.410 回答
1

对我来说,它在 Postgres/GreenPlum 中是这样工作的:

delete
from card where id in (
with cte as (
    select
        id,
        row_number() over(partition by code, card_id, parent_id order by id desc) as rn
    from card
)
select id from cte where rn > 1);
于 2017-12-05T10:59:20.733 回答