Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sqlite/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 删除重复行,但保留首选行_Sql_Sqlite - Fatal编程技术网

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);