我有一个简单的数据库表
create table demo (
id integer PRIMARY KEY,
fv integer,
sv text,
rel_id integer,
FOREIGN KEY (rel_id)
REFERENCES demo(id));
我希望删除按fv
和sv
分组的所有重复行。这已经是一个fairly popular question,有很好的答案。
但我需要扭曲这种情况。在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
---+----+------------------+-------
1 | 1 | 'somestring' | NULL
3 | 1 | 'anotherstring' | NULL
4 | 2 | 'somemorestring' | 3
将是有效的结果。
id | fv | sv | rel_id
---+----+------------------+-------
3 | 1 | 'anotherstring' | NULL
4 | 2 | 'somemorestring' | 3
5 | 1 | 'somestring' | 3
不会。由于第一个条目NULL
为rel_id
,其总统职位高于NOT NULL
。
我目前有这个(这是基本重复问题的答案)作为删除重复项的查询,但我不知道如何继续修改查询以满足我的需求。
DELETE FROM demo
WHERE id NOT IN (SELECT min(id) as id
FROM demo
GROUP BY fv,sv)
只要NOT NULL
条目在NULL
条目之前插入数据库,NOT NULL
条目就不会被删除。保证rel_id
始终指向rel_id
为NULL
的条目,因此不存在删除引用条目的危险。此外,保证在rel_id IS NULL
的同一组中不会有两行。因此,rel_id IS NULL
行对整个表来说都是唯一的。
或作为基本算法:
fv
和sv
rel_id IS NULL
行。如果有保留该行(并删除其余行)。否则选择一行,然后删除其余部分。答案 0 :(得分:0)
我好像已经解决了
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);
通过在内部SELECT
中选择仅rel_id
具有值NULL
的行或在GROUP BY
参数上匹配的所有行,通过使用反条件为rel_id IS NULL
行的存在。但我的查询看起来真的无效。作为一个天真的假设会使运行时间至少为O(n^2)
。