我可以像这样匹配一组条件:
select ID from FOO where col1=1 and col2=2 and col3=3
Run Code Online (Sandbox Code Playgroud)
但是,如果我有一个数组,[(1,2,3), (4,5,6), (7,8,9)]
在这种情况下如何获取 ID 呢?
为了澄清,我想要一种将每个元组与三列匹配的方法。如果它被打破,它将是:
select ID from FOO where col1=1 and col2=2 and col3=3
select ID from FOO where col1=4 and col2=5 and col3=6
select ID from FOO where col1=7 and col2=8 and col3=9
Run Code Online (Sandbox Code Playgroud)
如果我必须循环,就这样吧,我认为可能有一种更优雅的方法来做到这一点。
我的 sqlite 版本是 3.8.11,它随 Python 3.5.1 一起提供。
And*_*y M 11
在您的情况下,有多种方法可以通过单个查询获取多个 ID。
首先,您可以只使用一系列单个 SELECT:
SELECT ID FROM FOO WHERE col1=1 AND col2=2 AND col3=3;
SELECT ID FROM FOO WHERE col1=4 AND col2=5 AND col3=6;
SELECT ID FROM FOO WHERE col1=7 AND col2=8 AND col3=9;
Run Code Online (Sandbox Code Playgroud)
SELECT ID FROM FOO WHERE col1=1 AND col2=2 AND col3=3
UNION ALL
SELECT ID FROM FOO WHERE col1=4 AND col2=5 AND col3=6
UNION ALL
SELECT ID FROM FOO WHERE col1=7 AND col2=8 AND col3=9;
Run Code Online (Sandbox Code Playgroud)
现在您有一个返回所有匹配 ID 的语句。它必须像元组一样多次通过表,但如果数量不大,那应该不是问题。
另一种方法是使用 OR 运算符来组合条件:
SELECT
ID
FROM
FOO
WHERE col1=1 AND col2=2 AND col3=3
OR col1=4 AND col2=5 AND col3=6
OR col1=7 AND col2=8 AND col3=9
;
Run Code Online (Sandbox Code Playgroud)
您还可以添加括号以使意图绝对明确:
WHERE (col1=1 AND col2=2 AND col3=3)
OR (col1=4 AND col2=5 AND col3=6)
OR (col1=7 AND col2=8 AND col3=9)
Run Code Online (Sandbox Code Playgroud)
尽管 AND 的优先级高于 OR,因此无论哪种方式,结果都是相同的。
虽然简单得多,但第二种方法不一定更有效。在内部,OR-ed 表达式的每个成员都可以作为单独的查询实现,所有这些都与 UNION 组合。因此,实际上执行的查询可能与之前的查询非常相似,除了 UNION 与 UNION ALL 不完全相同,因为它具有结果重复数据删除的额外开销。如果您希望您的结果无论如何都是独一无二的,那么重复数据删除肯定是不必要的。
在这种情况下,您可能需要考虑这种方法:
SELECT
f.ID
FROM
FOO AS f
INNER JOIN
(
SELECT 1 AS col1, 2 AS col2, 3 AS col3
UNION ALL
SELECT 4, 5, 6
UNION ALL
SELECT 7, 8, 9
) AS p ON f.col1 = p.col1
AND f.col2 = p.col2
AND f.col3 = p.col3
;
Run Code Online (Sandbox Code Playgroud)
该p
派生表返回参数值的行集。该行集被连接在一起FOO
,因此用作过滤器。
尽管最后一个查询看起来比第一个查询更冗长,但它可能是三种方法中最有效的。
不过,如果 SQLite 允许您在 FROM 子句中使用 VALUES 行构造函数,它看起来会稍微优雅一些:
SELECT
f.ID
FROM
FOO AS f
INNER JOIN
(
VALUES
(1, 2, 3),
(4, 5, 6),
(7, 8, 9)
) AS p (col1, col2, col3)
ON f.col1 = p.col1
AND f.col2 = p.col2
AND f.col3 = p.col3
;
Run Code Online (Sandbox Code Playgroud)
但是,您可以使用 CTE(公用表表达式,也称为 WITH 子句)重写它,如下所示:
WITH p (col1, col2, col3) AS
(
VALUES
(1, 2, 3),
(4, 5, 6),
(7, 8, 9)
)
SELECT
f.ID
FROM
FOO AS f
INNER JOIN p ON f.col1 = p.col1
AND f.col2 = p.col2
AND f.col3 = p.col3
;
Run Code Online (Sandbox Code Playgroud)
但是,也许最优雅的解决方案是这样的:
SELECT
ID
FROM
FOO
WHERE
(col1,col2,col3) IN ((1,2,3), (4,5,6), (7,8,9))
;
Run Code Online (Sandbox Code Playgroud)
如果 SQLite 支持该语法。
(感谢 ypercube??标准 SQL 的最后两个建议。)
但是,从版本 3.15 开始,SQLite 确实支持元组比较,正如a_horse_with_no_name所评论的,只是不支持上一个查询中的特定语法。只有在匹配子查询而不是显式指定的元组列表时,才可以使用 IN 谓词(感谢CL.的建议):
SELECT
ID
FROM
FOO
WHERE
(col1,col2,col3) IN (VALUES (1,2,3), (4,5,6), (7,8,9))
;
Run Code Online (Sandbox Code Playgroud)
或者您可以使用=
谓词比较元组:
SELECT
ID
FROM
FOO
WHERE
(col1,col2,col3) = (1,2,3)
OR
(col1,col2,col3) = (4,5,6)
OR
(col1,col2,col3) = (7,8,9)
;
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
9919 次 |
最近记录: |