2017-05-29 145 views
0

我有一個帶有displayName列的表,我添加了一個「唯一」約束。我試圖編寫一個遷移,將任何非唯一的displayName設置爲null,只保留具有較低用戶ID的displayName。這裏是我的查詢:在添加唯一約束的列中刪除重複的值

UPDATE "User" SET "displayName" = NULL 
      WHERE id IN (SELECT id, 
         FROM (SELECT id, 
            ROW_NUMBER() OVER (partition BY "displayName" ORDER BY id) AS rnum 
           FROM "User") t 
         WHERE t.rnum > 1); 

當我試圖運行遷移我回來了「錯誤:語法錯誤在或接近」FROM「」。

感謝

+0

用您正在使用的數據庫標記您的問題。此外,樣本數據和期望的結果將有助於傳達您正在使用的內容。 –

+3

','在子查詢中的id後面。 –

回答

1

爲什麼不直接寫爲:

UPDATE "User" 
    SET "displayName" = NULL 
    WHERE id > (SELECT MIN(u2.id) 
       FROM "User" u2 
       WHERE u2."displayName" = u."displayName" 
       ); 

無論數據庫使用的是,這也應該是能夠在"User"("displayName", id)採取指數的優勢。

0

更簡單的方法是使用CTE或子查詢,像這樣....

WITH X AS 
(
SELECT id 
    , [displayName] 
    , ROW_NUMBER() OVER (partition BY [displayName] ORDER BY id) AS rnum 
FROM [User] 
) 
UPDATE X 
SET [displayName] = NULL 
WHERE rnum > 1 

OR

UPDATE X 
SET [displayName] = NULL 
FROM (
     SELECT id 
      , [displayName] 
      , ROW_NUMBER() OVER (partition BY [displayName] ORDER BY id) AS rnum 
     FROM [User] 
    ) x 
WHERE rnum > 1 

而且在一個側面說明,在唯一約束顯示名稱真的:S ....

+0

老闆的命令。絕對不是我的想法。 – user3143105

+0

請注意,方括號在SQL標識符中無效。而問題只是用'sql'標記而不是特定的DBMS產品(並且該問題也使用標準雙引號) –