在某些情况下将重复值设置为NULL

时间:2018-08-23 09:17:44

标签: sql sqlite duplicates

我有一个具有单个关系的相当大的SQL数据库(当前为SQLite3):

CREATE TABLE sometable (
    `name` TEXT,
    `position` INTEGER
);

由于数据的性质,没有主键或约束,在nameposition列上只有非唯一索引。现在,我需要将name列设置为NULL,其中名称是重复的,但位置不是。重复的(name,position)对可以,并且不能更改。

之前:

name | position
-----+---------
a    | 5
a    | 5
b    | 7
b    | 8
c    | 6
c    | 7
c    | 7
d    | 6

之后:

name | position
-----+---------
a    | 5
a    | 5
NULL | 6
NULL | 7
NULL | 6
NULL | 7
NULL | 8
d    | 6

我只能保留的行是名称/位置关联中没有歧义的行。但是,只要该名称不与另一个职位相关联,就必须保留重复的名称/职位对。

我找不到合适的SQL语句来做到这一点。

2 个答案:

答案 0 :(得分:1)

尝试使用相关子查询进行更新,以检查给定名称是否应由NULL替换。下面的子查询按名称进行汇总,然后检查是否存在多个位置。如果是这样,那么该名称将是更新的候选名称。

UPDATE sometable
SET name = NULL
WHERE EXISTS (SELECT name FROM sometable t2
              WHERE sometable.name = t2.name
              GROUP BY name
              HAVING COUNT(DISTINCT position) > 1);

答案 1 :(得分:0)

您可以将union allnot exists/exists结合使用:

select t.name, t.position 
from table t
where not exists (select 1 from table t1 where t1.name = t.name and t.position <> t1.position)
union all
select null, t.position 
from table t
where exists (select 1 from table t1 where t1.name = t.name and t.position <> t1.position);

因此,update版本为:

update table t
     set t.name = null
where exists (select 1 from table t1 where t1.name = t.name and t1.position <> t.position);