在 SQL (SQLite3) 中将 IN 与元组集一起使用

Posted

技术标签:

【中文标题】在 SQL (SQLite3) 中将 IN 与元组集一起使用【英文标题】:Using IN with sets of tuples in SQL (SQLite3) 【发布时间】:2010-04-08 01:22:03 【问题描述】:

我在 SQLite3 数据库中有下表:

CREATE TABLE overlap_results (
neighbors_of_annotation varchar(20),
other_annotation varchar(20),
set1_size INTEGER,
set2_size INTEGER,
jaccard REAL,
p_value REAL,
bh_corrected_p_value REAL,
PRIMARY KEY (neighbors_of_annotation, other_annotation)
);

我想执行以下查询:

SELECT * FROM overlap_results WHERE 
(neighbors_of_annotation, other_annotation)
IN (('16070', '8150'), ('16070', '44697'));

也就是说,我有几个注释 ID 元组,我想获取 每个元组的记录。 sqlite3 提示给了我以下信息 错误:

SQL error: near ",": syntax error

如何正确地将其表达为 SQL 语句?


编辑我意识到我没有很好地解释我真正追求的是什么。让我再试试这个。

如果有人给了我他们感兴趣的neighbors_of_annotation 中的任意术语列表,我可以编写如下 SQL 语句:

SELECT * FROM overlap_results WHERE 
neighbors_of_annotation
IN (TERM_1, TERM_2, ..., TERM_N);

但是现在假设那个人想给我一对术语,如果(TERM_1,1, TERM_1,2)(TERM_2,1, TERM_2,2),...,(TERM_N,1, TERM_N,2),其中TERM_i,1neighbors_of_annotation中,TERM_i,2在@中987654332@。 SQL 语言是否提供了一种同样优雅的方式来为感兴趣的对(元组)制定查询?

最简单的解决方案似乎是为这些对创建一个新表, 然后将该表与要查询的表连接起来,只选择 第一项和第二项匹配的行。创建大量 AND / OR 语句看起来很吓人且容易出错。

【问题讨论】:

【参考方案1】:

我从未见过这样的 SQL。如果它存在,我会怀疑它是一个非标准扩展。试试:

SELECT * FROM overlap_results
WHERE neighbors_of_annotation = '16070'
AND   other_annotation = '8150'
UNION ALL SELECT * FROM overlap_results
WHERE neighbors_of_annotation = '16070'
AND   other_annotation = '44697';

换句话说,从您的元组构建动态查询,但是作为一系列联合,或者作为 OR 中的一系列 AND:

SELECT * FROM overlap_results
WHERE (neighbors_of_annotation = '16070' AND other_annotation =  '8150')
OR    (neighbors_of_annotation = '16070' AND other_annotation = '44697');

所以,而不是代码(伪代码,只在我的脑海中测试过,所以调试是你的责任),例如:

query  = "SELECT * FROM overlap_results"
query += " WHERE (neighbors_of_annotation, other_annotation) IN ("
sep = ""
for element in list:
    query += sep + "('" + element.noa + "','" + element.oa + "')"
    sep = ","
query += ");"

你会得到类似的东西:

query  = "SELECT * FROM overlap_results "
sep = "WHERE "
for element in list:
    query += sep + "(neighbors_of_annotation = '" + element.noa + "'"
    query += " AND other_annotation = '" + element.oa + "')"
    sep = "OR "
query += ";"

【讨论】:

【参考方案2】:

我不知道有任何 SQL 方言支持 IN 子句中的元组。我认为你被困住了:

SELECT * FROM overlap_results WHERE (neighbors_of_annotation = '16070' and other_annotation = '8150') or (neighbors_of_annotation = '16070' and other_annotation = '44697')

当然,这个特定的查询可以简化为:

SELECT * FROM overlap_results WHERE neighbors_of_annotation = '16070' and (other_annotation = '8150' or other_annotation = '44697')

通常 SQL WHERE 子句谓词只允许过滤单列。

【讨论】:

这对两对来说是一个很好的解决方案。我更新了我的问题,注意我们可能会收到很多要搜索的配对。使用AND/ORs 构建查询很快就会变得很麻烦。

以上是关于在 SQL (SQLite3) 中将 IN 与元组集一起使用的主要内容,如果未能解决你的问题,请参考以下文章

列表与元组

将元组与元组序列中的某些元素匹配

Python3.7之列表与元组

列表与元组——自兴人工智能

Python教学课程分享3-列表与元组详解

在笛卡尔积中,元数与元组个数是相同的意思吗