2011-10-28 78 views
0

所以我知道剛夠SQL是危險的,沒有其他的東西。我正在開發一個應用程序,它需要顯示SQLite數據庫中的數據部分,並且能夠根據某些標準遍歷一些數據。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

請注意,如果返回多個行的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> 
+0

感謝有關ORDER BY的技巧中,我一直認爲結果通過ROWID默認爲訂購。我應該知道比承擔這種事情更好。我相信我讀了一個內部SELECT語句創建一個臨時表的地方。如果是這種情況,那麼從主SELECT語句返回的「rowid」是否反映了此臨時表中的rowid? – Gerald

+0

@傑拉德,是的,見我答案的附錄。 –

+0

感謝您的信息。但是,看起來它看起來像rowid反映了原始表的rowid而不是臨時表。我真正需要的是數據包子集的索引。即基於你的例子,如果我在tt中查詢了第一個「缺失」值1,我需要得到索引2而不是4,以反映子集內的索引。對不起,如果我不清楚這一點。 – Gerald