在 Postgresql 中的多个列上执行 WHERE IN

Posted

技术标签:

【中文标题】在 Postgresql 中的多个列上执行 WHERE IN【英文标题】:Doing a WHERE IN on multiple columns in Postgresql 【发布时间】:2011-07-13 00:01:15 【问题描述】:

我有一个表“answers”,其中包含一个索引的“problem_id”整数列、一个“times_chosen”整数列和一个 varchar 的“option”列。目前,“选项”列的唯一值是“A”、“B”、“C”和“D”,尽管稍后可能会扩展。当我知道每个答案的 issue_id 和选项时,我想将许多 (50-100) 答案的“times_chosen”值加一。

所以我需要一个类似的查询:

UPDATE answers
SET times_chosen = times_chosen + 1
WHERE (problem_id, option) IN ((4509, 'B'), (622, 'C'), (1066, 'D'), (4059, 'A'), (4740, 'A')...)

这可能吗?

【问题讨论】:

应该,至少我认为在 mysql 和 MSSQL 中应该。你试过了吗?您可以使用SET times_chosen = times_chosen 进行测试 哦,哇,它确实有效,就像我写的一样!它甚至使用索引!谢谢 Dirk - 如果您只是复制下面的回复作为答案,我很乐意接受。 嘿,我不知道这是有效的语法。这很方便=D @PreciousBodilyFluids 请在您的问题中添加一行确认它就像一个魅力 ^^ 【参考方案1】:

您可以加入各种虚拟表:

SELECT * FROM answers
JOIN (VALUES (4509, 'B'), (622, 'C'), (1066, 'D'), (4059, 'A'), (4740, 'A')) 
    AS t (p,o)
ON p = problem_id AND o = option

你可以用 UPDATE 做类似的事情。

【讨论】:

除了更酷之外,这个解决方案是否比@Dirk 的solution 更受欢迎? 这适用于 postgresql。我需要 spring jpa 的相应查询。你能帮忙吗? 这样更灵活,我们可以逐列更改操作符。【参考方案2】:

应该,至少我以前在其他 SQL 中做过。

你试过了吗?你可以用SET times_chosen = times_chosen测试一下

【讨论】:

【参考方案3】:

如果先将数据转换为数组,则可以这样做:

UPDATE answers
SET times_chosen = times_chosen + 1
WHERE ARRAY[problem_id::VARCHAR,option] IN ('4509,B', '622,C', ... )

但是,这将非常低效,因为它不能使用索引。使用@Frank Farmer 建议的 JOIN 是一个更好的解决方案:

UPDATE answers a
SET times_chosen = times_chosen + 1
FROM (VALUES (4509,'B'), (622,'C') ...) AS x (id,o)
    WHERE x.id=a.problem_id AND x.o=a.option;

【讨论】:

【参考方案4】:

你可能正在寻找

SELECT * FROM foo, bar WHERE foo.bob = "NaN" AND bar.alice = "Kentucky";

风格的语法。本质上,您使用 tablename.rowname 来指定您要查找的单个字段。为了正确排列所有内容,您添加 WHERE 子句以确保主键匹配:

...WHERE foo.primarykey = bar.primarykey

或类似的。您最好查找内部连接。

【讨论】:

以上是关于在 Postgresql 中的多个列上执行 WHERE IN的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 xpath 表达式在 PostgreSQL 中的 XML 列上创建索引?

如何在 Google Big Query 中的多个列上执行模式功能

PostgreSQL 中的高效全文搜索,在另一列上排序

在不相关列上的 Postgresql 错误中选择 Distinct

如何获得 PostgreSQL 中的两个平均值之间的差异,平均值在列上,最终表按两列分组?

Postgresql 查询的过滤条件中的列上的字符串操作如何影响它选择的计划