簡體   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