[英]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 中删除。
你可以这样做:
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,你可以将子查询移到一个:
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.