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

Pre*_*ids 27 sql postgresql

我有一个表'answers',带有索引的'problem_id'整数列,'times_chosen'整数列和'option'列,它是一个varchar.目前,"选项"列的唯一值是"A","B","C"和"D",但稍后可能会扩展.当我知道每个问题的problem_id和选项时,我希望将许多(50-100)个答案的'times_chosen'值加1.

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

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

这可能吗?

Fra*_*mer 21

您可以加入虚拟的各种表格:

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
Run Code Online (Sandbox Code Playgroud)

您可以使用UPDATE执行类似的操作.

  • 除了更酷之外,这个解决方案比 @Dirk 的[解决方案](/sf/answers/467105131/) 更受好评,还有什么原因吗? (4认同)

Dir*_*irk 11

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

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


Fli*_*mzy 5

如果首先将数据转换为数组,则可以执行此操作:

UPDATE answers
SET times_chosen = times_chosen + 1
WHERE ARRAY[problem_id::VARCHAR,option] IN ('{4509,B}', '{622,C}', ... )
Run Code Online (Sandbox Code Playgroud)

然而,这将非常低效,因为它无法使用索引。使用 @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;
Run Code Online (Sandbox Code Playgroud)