Выполнение WHERE IN на нескольких столбцах в Postgresql

У меня есть таблица "ответы" с индексированным столбцом целых чисел "problem_id", столбцом целого числа "times_chosen" и столбцом "option", который является varchar. В настоящее время единственными значениями для столбца "option" являются "A", "B", "C" и "D", хотя впоследствии они могут расширяться. Я хочу увеличивать на единицу значения times_chosen для многих (50-100) ответов, когда я знаю problem_id и вариант каждого из них.

Итак, мне нужен запрос, который выглядит примерно так:

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

Возможно ли это?

Ответы

Ответ 1

Он должен, по крайней мере, я сделал это раньше в других SQL.

Вы пробовали? Вы можете проверить его с помощью SET times_chosen = times_chosen

Ответ 2

Вы можете присоединиться к виртуальной таблице:

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.

Ответ 3

Вы можете сделать это, если сначала перенесите данные в массив:

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

Однако это будет невероятно неэффективно, поскольку он не может использовать индексы. Использование JOIN, предложенное @Frank Farmer, является гораздо лучшим решением:

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

или аналогичный. Вы бы хорошо посмотрели внутренние соединения.