SQLite находит специфичный для запроса индекс подзапроса - PullRequest
0 голосов
/ 29 октября 2011

Итак, я знаю достаточно 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-запроса, или указатели на соответствующую документацию или учебные пособия.

Спасибо!

(примечание: вопрос может не иметь смысла, так как он немного запутан в моих мыслях о том, как это объяснить, поэтому, если что-то не понятно, я попытаюсь уточнить.)

Edit: на самом деле я обнаружил, что делать это в коде C достаточно с точки зрения производительности, выполняя запрос всего набора результатов после начального индекса, выполняя LIMIT -1 OFFSET [startIndex], а затем пошагово продвигаясь, пока не найду следующее отсутствует пункт. Тем не менее, было бы неплохо узнать, есть ли способ сделать это только с помощью оператора SQL, для дальнейшего использования.

1 Ответ

1 голос
/ 29 октября 2011

Обратите внимание, что если инструкция 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: отображает ли "rowid", возвращаемый из основного оператора SELECT, идентификатор строкив этой временной таблице?

Да ...

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> 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...