我的sqlite表格式如下(例如,所有非空,而不是唯一的INTEGER):
time type data
1436268660 0 ...
1436268661 1 ...
1436268662 0 ...
1436268666 2 ...
1436268668 1 ...
有时候我需要删除每个类型的所有行,这些行比某些时间要早,但我需要从每种类型中保留最新的5行,即使它们比特定时间早。 换句话说,要保留每种类型的5个最新行,并且还要比指定时间(如果超过5个)更新,并删除其余部分。
因此,如果指定的时间是X而类型0的行比X早20行,则类型0没有任何操作(所有都足够新)。 此外,如果指定的时间是X并且类型0有5行都比X更旧,则不执行任何操作(其中不超过5个)。 但是,如果有例如7个条目且其中至少有2个条目早于X,则删除那些最早的条目。
到目前为止我的查询是什么。但这不正确。当该类型超过5时,它只删除早于X的所有行。如果他们都比X年龄大,那就剩下了。
DELETE FROM table WHERE rowid IN
(SELECT table.rowid FROM table JOIN
(SELECT type FROM table GROUP BY type HAVING COUNT(*) > 5)
USING (type) WHERE TIME < 14362685399);
正如您所看到的情况稍微复杂一点,因为我上面描述的“类型”实际上是多列的唯一组合(您可以替换为type1,type2,type3),但我想它不是那么重要为解决方案。 谢谢你的帮助。
time type0 type1 type2 data
1436268660 0 0 0 ...
1436268661 1 1 1 ...
1436268662 0 0 0 ...
1436268666 2 2 2 ...
1436268668 1 1 1 ...
编辑:基本上我需要删除所有不在的行:(比X更新)UNION(每种类型的5个最新条目)。 我只是不知道如何使用“每种类型的5个最新条目”创建结果。
答案 0 :(得分:2)
试试这个。我已将您的表格重命名为t
。
DELETE FROM t WHERE rowid IN(
SELECT a.rowid FROM t a
WHERE time < 14362685399
AND a.rowid NOT IN (
SELECT b.rowid FROM t b
WHERE a.type = b.type
ORDER BY b.time DESC
LIMIT 5
)
);
请注意,这可能对大型数据效率不高,因为每次需要时都会评估correlated subquery(可能每次在表中每个type
评估一次,或者甚至一次表中的每行,取决于查询的执行方式。)
顺便说一下,在支持它的SQL变体中,使用窗口函数可能会更好。例如,在Postgres。