Объединение большого количества условий в предложении SQLite WHERE - PullRequest
2 голосов
/ 28 января 2012

Мне нужно получить записи, которые соответствуют идентификаторам, хранящимся в списке. Запрос, сгенерированный во время выполнения, прост:

SELECT [whatever FROM sometable] WHERE (id = 1) or (id = 5) or (id = 33).

Что эквивалентно

SELECT [whatever FROM sometable] WHERE [id] IN (1, 5, 33);

Это нормально, но что, если список содержит сотни или тысячи идентификаторов? Это утверждение будет огромным, и в какой-то момент синтаксический анализатор SQL может выкрутиться, или, если это не так, производительность, вероятно, будет довольно плохой. Как я могу сделать это так, чтобы это не было так чувствительно к количеству извлекаемых записей?

(Причина, по которой я не могу просто циклически перебирать список и извлекать записи по одной, заключается в том, что мне нужна база данных для выполнения ORDER BY. Записи должны поступать из БД, упорядоченной по определенному полю, в то время список представляет записи, выбранные пользователем в сетке, которые могут быть отсортированы любым количеством способов. И да, я мог бы сортировать записи в коде после их извлечения, но это план Б, поскольку мне даже не нужно хранить все они в одной структуре данных, только чтобы быть правильно упорядоченными.)

Ответы [ 5 ]

5 голосов
/ 28 января 2012

Если у вас действительно будет так много идентификаторов, что вы беспокоитесь о кваках парсера SQL, вы можете сохранить их во временной таблице и выполнить перекрестное соединение.

Просто создайте таблицу с одним (первичным ключом) столбцом, идентификатором, затем заполните ее желаемыми идентификаторами и используйте что-то вроде:

SELECT [whatever] FROM [sometable] st, [idtable] it
WHERE st.id = it.id

Этот запрос не захлебнет парсер, и извлеченные строки будут ограничены теми, которые имеют идентификатор во временной таблице.

Это не не может быть временным столом, конечно, вы можете оставить его лежащим без дела, при условии, что вы гарантируете, что только одна «вещь» использует его одновременно.

1 голос
/ 28 января 2012

Не могли бы вы добавить эти элементы в таблицу и затем присоединиться к ней?

SELECT Whatever FROM TableA CROSS JOIN TableB ON TableA.ID = TableB.ID
0 голосов
/ 28 января 2012

Ваш язык программирования должен поддерживать подготовленные запросы, т.е.

 SELECT [whatever FROM sometable] WHERE (id = ?);

или:

 SELECT [whatever FROM sometable] WHERE (id = @id);

При подготовке запроса он доступен для повторного использования, и вы можете связать параметрык переменной на вашем родном языке программирования.Если этот поиск выполняется с высокой частотой, целесообразно сохранить подготовленные запросы на некоторое время.

Здесь есть полезное обсуждение:

0 голосов
/ 28 января 2012

Если значения в предложении where находятся в таблице, вы можете сделать это.

select id from foo where id in (select id from bar)
0 голосов
/ 28 января 2012

Предположительно, существует некоторая логика, связанная с определением списка идентификаторов для извлечения, может ли эта логика не быть включена в предложение where?Возможно, вы могли бы присоединиться к таблице, которая содержит некоторый идентификатор сеанса вместе с необходимыми идентификаторами?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...