时间:2011-10-28 23:37:45

标签: sql sqlite

所以我知道足够的SQL是危险的而不是其他的。我正在开发一个应用程序,它需要显示来自SQLite数据库的数据部分,并能够根据某些标准迭代一些数据。

所以我有一个看起来像这样的表:

create table packets( id INTEGER PRIMARY KEY, timestamp varchar(32), type varchar(32), source varchar(32), destination varchar(32), channel varchar(16), first_sequence integer, last_sequence integer, missing integer );

然后我有一个视图,它将根据某些标准显示部分或全部数据。

我们谈论的是一个包含数百万行的表,所以我无法将其全部加载到内存中。所以我有一个视图类,它根据视图中的索引单独询问每个项目。

例如,如果我显示所有通道值为“C”的数据包,并且视图已准备好绘制第一个项目,我将向数据库发出此查询:

SELECT * FROM packets WHERE channel='C' LIMIT 1 OFFSET 0

当它准备好绘制我做的第二个项目时

SELECT * FROM packets WHERE channel='C' LIMIT 1 OFFSET 1

等...

这很好用。我意识到这可能不是最佳的方式,但我只是想学习如何用SQLite最简单的方式来做,然后再担心优化。

现在问题是我需要能够根据其他搜索条件在此结果集中查找项目,并在原始结果集中获取索引。

例如,我需要能够遍历原始结果集中具有“缺失”值1的项目,并找出这些项目的视图索引。

如果我使用表格中的整个数据集,我想我可以用类似的东西来做:

SELECT rowid FROM packets WHERE rowid > [currentlySelectedRowID] AND missing=1 LIMIT 1

但是当我需要一个数据子集中的索引时,rowid并没有真正帮助我,而且我不知道如何在子集中找到索引而不单独遍历所有项目。

有关如何使用SQL查询执行此操作的任何想法,或者指向相关文档或教程的提示将不胜感激。

谢谢!

(请注意:这个问题可能没有意义,因为我在如何解释它时会有点复杂,所以如果不清楚我会尝试详细说明。)

编辑:实际上我发现通过执行LIMIT -1 OFFSET [startIndex]在初始索引之后查询整个结果集,从性能角度来看,在C代码中执行此操作就足够了,然后单步执行直到找到下一个缺失的项目。不过,为了将来的参考,知道是否有办法只使用SQL语句仍然会很好。

1 个答案:

答案 0 :(得分:1)

请注意,如果返回多行的SELECT语句没有ORDER BY子句,则返回行的顺序是未定义的。

订单对于您的初始查询似乎并不重要,但在您需要创建行的子集时将变得非常重要(因为您希望为子集的域使用相同的初始集)。

使用

SELECT rowid,* FROM packets WHERE channel='C' ORDER BY rowid LIMIT N? OFFSET M?

对结果强加订单。然后就可以了

SELECT rowid 
FROM (SELECT rowid,* FROM packets WHERE channel='C' ORDER BY rowid LIMIT N? OFFSET M?)
WHERE missing=1 LIMIT 1

在其中找到一个子集。

附录,re:从主SELECT语句返回的“rowid”是否反映了此临时表中的rowid?

...是

sqlite> create table packets (channel, missing);
sqlite> insert into packets values ('A',0);
sqlite> insert into packets values ('B',0);
sqlite> insert into packets values ('C',0);
sqlite> select * from packets;
A|0
B|0
C|0
sqlite> create temp table tt as SELECT rowid,* FROM packets WHERE channel='C';
sqlite> select rowid,* from tt;
3|3|C|0
sqlite> insert into packets values ('C',1);
sqlite> drop table tt;
sqlite> create temp table tt as SELECT rowid,* FROM packets WHERE channel='C';
sqlite> select rowid,* from tt;
3|3|C|0
4|4|C|1
sqlite>