如何在SQLite中删除2列作为复合主键的多行?

时间:2015-03-16 09:54:53

标签: sqlite delete-row composite-primary-key sql-delete

我需要删除SQLite表中的一些行,其中两列作为主键,如下所示:

DELETE FROM apt_lang 
WHERE (apt_fk, apt_lang_fk) NOT IN ((42122,"en"),(42123,"es"),(42123,"en"))

这适用于Oracle和MySQL,但不适用于SQLite。

有人能帮助我吗?

3 个答案:

答案 0 :(得分:3)

首先,找出要删除的行。 最简单的方法是加入:

SELECT *
FROM apt_lang
JOIN (SELECT 42122 AS apt_fk, 'en' AS apt_lang_fk UNION ALL
      SELECT 42123          , 'es'                UNION ALL
      SELECT 42123          , 'en'                         )
USING (apt_fk, apt_lang_fk)

要将其与DELTE一起使用,请使用EXISTS进行匹配检查:

DELETE FROM apt_lang
WHERE NOT EXISTS (SELECT 1
                  FROM apt_lang AS a2
                  JOIN (SELECT 42122 AS apt_fk, 'en' AS apt_lang_fk UNION ALL
                        SELECT 42123          , 'es'                UNION ALL
                        SELECT 42123          , 'en'                         )
                  USING (apt_fk, apt_lang_fk)
                  WHERE apt_fk      = apt_lang.apt_fk
                    AND apt_lang_fk = apt_lang.apt_lang_fk)

或获取子查询的ROWID并检查以下内容:

DELETE FROM apt_lang
WHERE rowid NOT IN (SELECT apt_lang.rowid
                    FROM apt_lang
                    JOIN (SELECT 42122 AS apt_fk, 'en' AS apt_lang_fk UNION ALL
                          SELECT 42123          , 'es'                UNION ALL
                          SELECT 42123          , 'en'                         )
                    USING (apt_fk, apt_lang_fk))

答案 1 :(得分:0)

是的,可以根据构建在多个列上的子查询从SQLite中删除行。这可以通过SQLite的连接“||”运算符来完成。这可能有助于展示一个例子。

<强>设定:

create table a (x,y); 
insert into a values ('A','B');
insert into a values ('A','C');

create table b (x,y);
insert into b values ('A','C');
insert into b values ('A','X');

显示表格

select * from a;
A|B
A|C

select * from b;
A|C
A|X

假设您要从表 a 中删除列x和列y与表 b 不匹配的行,则以下选择将完成该操作。

delete from a where x||y not in (select a.x||a.y from a,b where a.x=b.x and a.y=b.y);

<强>结果:

select * from a;
A|B

<强>摘要

这依赖于使用“||”运算符将多个列连接成一列。请注意,它也适用于计算值,但可能需要转换值。因此,只需使用“||”运算符...

进行一些转换即可
 select 9+12|| 'test';
 21 -- Note we lost 'test'

 select cast(9+12 as text)|| 'test';
 21test -- Good!  'test' is there.

答案 2 :(得分:0)

这应该有效:

DELETE FROM apt_lang WHERE (apt_fk, apt_lang_fk) NOT IN (VALUES (42122,"en"),(42123,"es"),(42123,"en"))