在PostgresSQL中将重复值设置为Null,保留其中一个值

时间:2019-02-27 02:50:34

标签: sql postgresql sql-update unique

我有一个这样的数据库:

id    name    email
0     Bill    bill@fakeemail.com
1     John    john@fakeemail.com
2     Susan   susan@fakeemail.com
3     Susan J susan@fakeemail.com

我想通过将值设置为null来删除重复的电子邮件,但在其中的一行中至少保留1封电子邮件(与哪一行无关)。

这样生成的数据库将如下所示:

id    name    email
0     Bill    bill@fakeemail.com
1     John    john@fakeemail.com
2     Susan   susan@fakeemail.com
3     Susan J 

我能够像这样定位行 SELECT COUNT(email) as count FROM users WHERE count > 1

但是无法弄清楚如何将值设置为null却仍然保留至少1。

2 个答案:

答案 0 :(得分:3)

更新具有相同email但具有更大id的行:

update my_table t1
set email = null
where exists (
    select from my_table t2
    where t1.email = t2.email and t1.id > t2.id
    );

Working example in rextester.

答案 1 :(得分:1)

您可以使用窗口分区为每个电子邮件组分配行号,然后使用该生成的行号修改除一个以外的所有行。像这样:

WITH annotated_persons AS(
SELECT
 id,
 name,
 email,
 ROW_NUMBER () OVER (PARTITION BY email) AS i
FROM
 persons;
)
UPDATE persons
SET email = null
WHERE id = annotated_persons.id AND annotated_persons.i <> 1

您可能必须使用另一个子查询来收集行号!= 1的人员的ID,然后将更新查询更改为

WHERE id IN person_ids

自从我使用窗户以来已经有一段时间了。