【问题标题】:order of search for Sqlite's "IN" operator guaranteed?保证搜索 Sqlite 的“IN”运算符的顺序?
【发布时间】:2019-10-03 17:07:46
【问题描述】:

我正在执行类似于

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

我是否保证它将首先搜索name1,然后搜索name2,等等?这样,通过将我的输出限制为 1,我知道我根据 IN 子句中的项目顺序找到了第一个命中?

更新:经过一些测试,无论IN 顺序如何,它似乎总是返回索引中的第一个命中。它使用名称索引的顺序。有什么方法可以强制执行搜索顺序吗?

【问题讨论】:

  • 我保证它会先搜索 name1,然后搜索 name2,等等? 不,它不是这样工作的。

标签: sqlite deterministic in-operator


【解决方案1】:

返回的行的顺序不保证与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 将返回更接近列表开头的第一个。

实现相同结果的另一种方法是使用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 

这样您就不必重复列表两次。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    • 1970-01-01
    • 2012-05-22
    • 1970-01-01
    • 2016-03-03
    • 2013-01-15
    • 1970-01-01
    相关资源
    最近更新 更多