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

时间:2011-07-13 00:01:16

标签: 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')...)

这可能吗?

4 个答案:

答案 0 :(得分:19)

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

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做类似的事情。

答案 1 :(得分:8)

应该,至少我之前在其他SQL中已经完成了。

你试过吗?您可以使用SET times_chosen = times_chosen

进行测试

答案 2 :(得分: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;

答案 3 :(得分:0)

你可能正在寻找

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

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

...WHERE foo.primarykey = bar.primarykey

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