Sql 删除重复行,但保留首选行
我有一个简单的数据库表Sql 删除重复行,但保留首选行,sql,sqlite,Sql,Sqlite,我有一个简单的数据库表 create table demo ( id integer PRIMARY KEY, fv integer, sv text, rel_id integer, FOREIGN KEY (rel_id) REFERENCES demo(id)); 我想删除按fv和sv分组的所有重复行。这已经是一个很好的答案。 但我需要扭转这种局面。在rel_id为NULL的情况下,我希望保留该行。在任何其他情况下,任何事情都会发生 因此,
create table demo (
id integer PRIMARY KEY,
fv integer,
sv text,
rel_id integer,
FOREIGN KEY (rel_id)
REFERENCES demo(id));
我想删除按fv
和sv
分组的所有重复行。这已经是一个很好的答案。
但我需要扭转这种局面。在rel_id
为NULL
的情况下,我希望保留该行。在任何其他情况下,任何事情都会发生
因此,通过使用以下值
insert into demo (id,fv,sv,rel_id)
VALUES (1,1,'somestring',NULL),
(2,2,'somemorestring',1),
(3,1,'anotherstring',NULL),
(4,2,'somemorestring',3),
(5,1,'somestring',3)
或者
id | fv | sv | rel_id
---+----+------------------+-------
1 | 1 | 'somestring' | NULL
2 | 2 | 'somemorestring' | 1
3 | 1 | 'anotherstring' | NULL
或
将是有效的结果。何处为
id | fv | sv | rel_id
---+----+------------------+-------
3 | 1 | 'anotherstring' | NULL
4 | 2 | 'somemorestring' | 3
5 | 1 | 'somestring' | 3
不会的。因为第一个条目有NULL
作为rel\u id
,它在notnull
之上担任主席
我目前将此(这是关于基本重复问题的答案)作为删除重复项的查询,但我不确定如何继续修改查询以满足我的需要
DELETE FROM demo
WHERE id NOT IN (SELECT min(id) as id
FROM demo
GROUP BY fv,sv)
只要在NULL
条目之前将NOT NULL
条目插入数据库中,NOT NULL
条目将不会被删除。可以保证rel_id
始终指向rel_id
为NULL
的条目,因此不存在删除引用条目的危险。此外,保证同一组中不会有两行rel\u id为NULL
。因此,具有rel_id的行为空
对于整个表是唯一的
或者作为基本算法:
fv
和sv
rel\u id为NULL的行。如果有,保留该行(并删除其余行)。否则,从您选择的行中选择一行并删除其余行
我似乎已经解决了
DELETE FROM demo
WHERE id NOT IN (SELECT min(id) as id
FROM demo AS out_buff
WHERE rel_id IS NULL OR
NOT EXISTS (SELECT id FROM demo AS in_buff
WHERE rel_id IS NULL AND
in_buff.fv = out_buff.fv AND
in_buff.sv = out_buff.sv)
GROUP BY fv,sv);
通过在内部
中选择仅选择rel\u id
值为NULL
的行,或选择GROUP by
参数上匹配的所有行,使用反条件来确定存在rel\u id为NULL的行。但我的查询看起来确实无效。作为一个幼稚的假设,运行时间至少要O(n^2)
我知道您在试图解决这个问题上做了大量的工作,但我无法明确地完成任务。是否存在要删除rel\u id=NULL
的记录的条件?如果不是,只需将rel\u id不为NULL的添加到内部选择@KirillSlatin,这将杀死rel\u id
中存在NULL
条目的任何行。我将在进一步解释中进行编辑。您有两个嵌套查询。它可能在大型数据集上存在性能问题。如果我正确理解了你的解释,你需要
DELETE FROM demo
WHERE id NOT IN (SELECT min(id) as id
FROM demo AS out_buff
WHERE rel_id IS NULL OR
NOT EXISTS (SELECT id FROM demo AS in_buff
WHERE rel_id IS NULL AND
in_buff.fv = out_buff.fv AND
in_buff.sv = out_buff.sv)
GROUP BY fv,sv);