簡體   English   中英

Postgres 更新列,沖突時忽略此行

[英]Postgres update column, on conflict ignore this row

我有一張桌子,上面有emailsecondary_email email列具有唯一約束,而secondary_email可以跨行重復。

我必須編寫一個查詢以將secondary_email復制到email 如果有沖突,則忽略此行。

這個查詢

UPDATE users SET email = secondary_email
WHERE NOT EXISTS
(SELECT 1 FROM users WHERE email=secondary_email)

仍然拋出錯誤ERROR: duplicate key value violates unique constraint "users_email_key"

之前的用戶

+----+-------+-----------------+
| id | email | secondary_email |
+----+-------+-----------------+
| 1  | NULL  | NULL            |
| 2  | NULL  | NULL            |
| 3  | NULL  |                 |
| 4  | NULL  | e1@example.com  |
| 5  | NULL  | e1@example.com  |
| 6  | NULL  | e2@example.com  |
+----+-------+-----------------+

用戶之后

+----+----------------+-----------------+
| id | email          | secondary_email |
+----+----------------+-----------------+
| 1  | NULL           | NULL            |
| 2  | NULL           | NULL            |
| 3  | NULL           |                 |
| 4  | e1@example.com | e1@example.com  |
| 5  | NULL           | e1@example.com  |
| 6  | e2@example.com | e2@example.com  |
+----+----------------+-----------------+

您需要表別名來修復您的查詢:

UPDATE users u
    SET email = u.secondary_email
    WHERE NOT EXISTS (SELECT 1 FROM users u2 WHERE u2.email = u.secondary_email);

對於您的整體問題,請檢查列中是否存在重復項:

UPDATE users u
    SET email = u.secondary_email
    FROM (SELECT secondary_email, COUNT(*) as cnt
          FROM users u
          GROUP BY secondary_email
          HAVING COUNT(*) = 1
         ) s
    WHERE s.secondary_email = u.secondary_email AND
          NOT EXISTS (SELECT 1 FROM users u2 WHERE u2.email = u.secondary_email);

或者選擇第一個:

UPDATE users u
    SET email = u.secondary_email
    FROM (SELECT u.*,
                 ROW_NUMBER() OVER (PARTITION BY secondary_email ORDER BY user_id) as seqnum
          FROM users u
         ) s
    WHERE s.user_id = u.user_id AND
          s.seqnum = 1 AND
          NOT EXISTS (SELECT 1 FROM users u2 WHERE u2.email = u.secondary_email);

注意:這也會過濾掉NULL值,這似乎是個好主意。

是一個 db<>fiddle。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM