[英]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.