我需要获取数据库中特定行的列,由多个列标识。我想使用 IN 查询分批执行此操作。
在单列的情况下,很容易:
SELECT id FROM foo WHERE a IN (1,2,3,4)
但是当我尝试多列时出现语法错误
SELECT id FROM foo WHERE (a,b) IN ((1,2), (3,4), (5,6))
有没有办法做到这一点?我不能只做两个 IN 子句,因为它可能会返回额外的行并且也不使用多列索引。
这是 Declan_K 的想法:
为了能够使用多列索引而不必更新单独的列,您必须将查找值放入可以加入的表中:
CREATE TEMPORARY TABLE lookup(a, b);
INSERT INTO lookup VALUES ...;
CREATE INDEX lookup_a_b ON lookup(a, b);
SELECT id FROM foo JOIN lookup ON foo.a = lookup.a AND foo.b = lookup.b;
(索引实际上不是必需的;如果省略它,SQLite 查询优化器将被迫查找表lookup
中的记录foo
,而不是相反。)
如果要避免使用临时表,可以使用子查询动态构建它:
SELECT id
FROM foo
JOIN (SELECT 1 AS a, 2 AS b UNION ALL
SELECT 3 , 4 UNION ALL
SELECT 5 , 6 ) AS lookup
ON foo.a = lookup.a
AND foo.b = lookup.b
这仍然可以在foo(a,b)
.
此命令应在 (a, b) 上使用索引:
SELECT id FROM foo WHERE a = 1 and b = 2
UNION ALL
SELECT id FROM foo WHERE a = 3 and b = 4
UNION ALL
SELECT id FROM foo WHERE a = 5 and b = 6
如果你有一个长度的对列表,写起来很乏味,但这可以自动化。
我认为您真正想要的是另一个包含键/值对的(字符串)列,以便您可以专门查询组合。就像是:
SELECT id FROM foo WHERE c IN ('1,2', '3,4', '5,6')
您可以使用以下内容填充新列:
UPDATE foo SET c = a||','||b
您可能需要将 a 和 b 转换为字符串,但完成后,连接将是答案。
SELECT id FROM foo WHERE a||'_'||b IN ('1_2', '3_4', '5_6')