порядок поиска оператора Sqlite "IN" гарантирован? - PullRequest
0 голосов
/ 03 октября 2019

Я выполняю запрос Sqlite3, аналогичный

SELECT * FROM nodes WHERE name IN ('name1', 'name2', 'name3', ...) LIMIT 1

Гарантируется ли, что он будет искать сначала name1, name2, и т. Д.? Таким образом, ограничивая мой вывод до 1, я знаю, что я нашел первый удар в соответствии с моим порядком элементов в предложении IN?

Обновление: при некотором тестировании это кажется всегдавернуть первое попадание в индексе независимо от порядка IN. Это использует порядок индекса на имя. Есть ли какой-нибудь способ обеспечить порядок поиска?

1 Ответ

1 голос
/ 03 октября 2019

Порядок возвращаемых строк не обязательно соответствует порядку элементов в скобках после IN. Что вы можете сделать, это использовать ORDER BY в своем утверждении с использованием функции INSTR():

SELECT * FROM nodes 
WHERE name IN ('name1', 'name2', 'name3') 
ORDER BY INSTR(',name1,name2,name3,', ',' || name || ',')
LIMIT 1

Этот код использует тот же список из предложения IN, что истрока, в которой элементы расположены в одинаковом порядке, объединены и разделены запятыми, при условии, что элементы не содержат запятых. Таким образом, результаты упорядочиваются по их положению в списке, а затем LIMIT 1 возвращает 1-й из них, который находится ближе к началу списка. Другим способом достижения тех же результатов является использование CTE , который возвращает список вместе с Id, который служит в качестве требуемого порядка результатов, который будет присоединен к таблице:

WITH list(id, item) AS (
  SELECT 1, 'name1' UNION ALL 
  SELECT 2, 'name2' UNION ALL 
  SELECT 3, 'name3' 
)
SELECT n.* 
FROM nodes n INNER JOIN list l
ON l.item = n.name 
ORDER BY l.id
LIMIT 1 

Или:

WITH list(id, item) AS (
  SELECT * FROM (VALUES 
    (1, 'name1'), (2, 'name2'), (3, 'name3')
  )
)
SELECT n.* 
FROM nodes n INNER JOIN list l
ON l.item = n.name 
ORDER BY l.id
LIMIT 1 

Таким образом, вам не нужно повторять список дважды.

...