2017-12-14 29 views
1

私はsqlite3 DBを持っています。各行は自動インクリメントidとなり、値はNULLになります。私はnullを持つ末尾を削除する必要があります(理想的には、このセグメントから最も古いnullレコードを保持する)。 たとえば、id = 12..16(または理想的には13..16)の行を削除したいと思います。sqliteでNULLを使用してtailを選択するにはどうすればよいですか?

これはどのようにsqliteで行うことができますか?

CREATE TABLE tail (id INTEGER PRIMARY KEY, val TEXT); 
INSERT INTO "tail" VALUES(1,'5'); 
INSERT INTO "tail" VALUES(2,'7'); 
INSERT INTO "tail" VALUES(3,'100'); 
INSERT INTO "tail" VALUES(4,'150'); 
INSERT INTO "tail" VALUES(5,NULL); 
INSERT INTO "tail" VALUES(6,NULL); 
INSERT INTO "tail" VALUES(7,'120'); 
INSERT INTO "tail" VALUES(8,'150'); 
INSERT INTO "tail" VALUES(9,'152'); 
INSERT INTO "tail" VALUES(10,NULL); 
INSERT INTO "tail" VALUES(11,'152'); 
INSERT INTO "tail" VALUES(12,NULL); 
INSERT INTO "tail" VALUES(13,NULL); 
INSERT INTO "tail" VALUES(14,NULL); 
INSERT INTO "tail" VALUES(15,NULL); 
INSERT INTO "tail" VALUES(16,NULL); 

私は2つのステップで簡単に行うことができ、何かのように:

to_delete = [] 
for row in query("SELECT * FROM tail ORDER BY -id"): 
    if row.id IS NOT NONE: 
     break 
    to_delete.add(row.id) 
# optionally: to_delete.remove_last() 
query("DELETE FROM tail WHERE id IN (?)", to_delete) 

しかし、これはトランザクションではない、と私は達成するために使用することができ、いくつかの巧妙なトリックがあるという感覚を持っていますこれは、単一のsqliteステートメントです。

+0

を理由だけ 'valがnull'なのである尾から削除しませんか? sqliteに精通していないので、そこに構文を助けることはできません。 –

+0

@JacobH他の計算のために、末尾のvalを除くすべてのval = NULLが必要です。 –

答えて

1

あなたは使用することができます。

delete from tail 
    where id > (select max(t2.id) from tail t2 where t2.val is not null) and 
      val is null and 
      id <> (select max(t3.id) from tail t3 where t3.val is null); 
+0

それは、ゴードンに感謝します。ところで、 'valがnullで冗長でないか、何かを見逃しましたか? –

+0

@MichałŠrajer。 。 。はい。このような状況下では、それは冗長です。 –

関連する問題