繁体   English   中英

如何从 Postgres 中的 CTE(公用表表达式)中删除记录

[英]How to delete records from CTE (Common Table Expression) in Postgres

我在 Postgres 中使用 CTE 编写了以下查询。 现在我无法从中删除记录。

WITH cte AS (
    SELECT 
   
        firstname, 
        lastname, 
        country, 
        ROW_NUMBER() OVER (
            PARTITION BY 
                firstname, 
                lastname, 
                country
        ) row_num
     FROM 
        employee
) 
delete  from cte
where row_num >1

当我运行此查询时,它显示错误:

关系“cte”不存在

这是我的表'员工'的样本

id  firstname  lastname  country
1   "Raj"      "Gupta"   "India"
2   "Raj"      "Gupta"   "India"
3   "Mohan"    "Kumar"   "USA"
4   "James"    "Barry"   "UK"
5   "James"    "Barry"   "UK"
6   "James"    "Barry"   "UK"

无法从 CTE 中删除。

你可以这样做:

演示:db<>小提琴

DELETE FROM employee
WHERE id IN (
    SELECT
        id
    FROM (
        SELECT
            id,
            ROW_NUMBER() OVER (PARTITION BY firstname, lastname, country) row_num
        FROM 
            employee
    ) s
    WHERE row_num > 1
)

如果你仍然想使用 CTE,你可以将子查询移到一个:

演示:db<>小提琴

WITH cte AS (
    SELECT
        id
    FROM (
        SELECT
            id,
            ROW_NUMBER() OVER (PARTITION BY firstname, lastname, country) row_num
        FROM 
            employee
    ) s
    WHERE row_num > 1
)
DELETE FROM employee
WHERE id IN (SELECT * FROM cte)

您不能从 postgresql 的 CTE 表中删除记录。 尽管在 SQLSERVER 等其他数据库服务器中也是可能的。 您可以查看 postgresql 的CTE文档。

我认为更好的情况是在创建 CTE 的步骤中过滤不需要的行(不删除)

WITH cte AS (
    SELECT 
        firstname, 
        lastname, 
        country, 
        ROW_NUMBER() OVER (
            PARTITION BY 
                firstname, 
                lastname, 
                country
        ) row_num
     FROM employee
     WHERE row_num >1
)

我建议使用:

delete from employee e
    where e.id > (select min(e2.id)
                  from employee e2
                  where e2.firstname = e.firstname and
                        e2.lastname = e.lastname and 
                        e2.country = e.country
                 );

这是标准的 SQL,将在 SQL 服务器和 Postgres 中工作。

与 SQL 服务器版本的唯一区别是如何处理NULL值。 这将它们都视为“不同”,因此匹配的NULL值不会被视为匹配。 这可能不是您的数据中的问题,但您可以使用:

                  where e2.firstname is not distinct from e.firstname and
                        e2.lastname is not distinct from e.lastname and 
                        e2.country is not distinct from e.country

如果您希望NULL值匹配。

请注意,原始版本应该能够使用(lastname, firstname, country, id)上的索引(在任一数据库中)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM