Sql Postgres更新列上的冲突忽略此行

Sql Postgres更新列上的冲突忽略此行,sql,postgresql,sql-update,Sql,Postgresql,Sql Update,我有一张带有电子邮件和辅助电子邮件的表格email列具有唯一的约束,而secondary\u email可以跨行重复 我必须写一个查询,将辅助电子邮件复制到电子邮件。如果存在冲突,则忽略该行。 这个问题 UPDATE users SET email = secondary_email WHERE NOT EXISTS (SELECT 1 FROM users WHERE email=secondary_email) 仍然抛出错误错误:重复键值违反唯一约束“users\u email\u key

我有一张带有
电子邮件
辅助电子邮件
的表格
email
列具有唯一的约束,而
secondary\u email
可以跨行重复

我必须写一个查询,将
辅助电子邮件
复制到
电子邮件
。如果存在冲突,则忽略该行。

这个问题

UPDATE users SET email = secondary_email
WHERE NOT EXISTS
(SELECT 1 FROM users WHERE email=secondary_email)
仍然抛出错误
错误:重复键值违反唯一约束“users\u email\u 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
值,这似乎是个好主意


是一个dbfiddle。

仍然得到相同的约束错误注释。如果多个次要电子邮件列相同,则会出现重复错误。更新一行后,尝试更新另一行时将出现错误。where子句在您开始更新之前进行计算,因此它不会删除这些内容。@Gordon您上次的查询确实有效,但仅使用
secondary\u email
@Gordon I removed
s.seqnum=1
更新了您上次查询中的第一行,希望它能更新所有行。但现在我得到了相同的重复键错误。@BjarniRagnarsson在用户表之前和之后添加了一个例子。