Обновление и возврат PostgreSQL - PullRequest
0 голосов
/ 10 ноября 2018

Допустим, у меня есть таблица с именем t в Postgres:

   id   | group_name | state
-----------------------------
   1    |   group1   |   0
   2    |   group1   |   0
   3    |   group1   |   0

Мне нужно обновить state строки по ID, а также вернуть некоторые вещи:

  • Старое государство
  • Оставшееся количество строк в той же группе, которые имеют state = 0

У меня есть запрос, чтобы сделать это следующим образом:

UPDATE t AS updated SET state = 1
FROM t as original
WHERE 
    updated.id = original.id AND
    updated.id = :some_id
RETURNING
    updated.state AS new_state,
    original.state AS old_state,
    (
        SELECT COUNT(*) FROM t 
        WHERE 
            group_name = updated.group_name AND
            state = 0
    ) as remaining_count;

Однако, похоже, что подзапрос в RETURNING выполняется до обновления завершено, и у меня остается remaining_count, который выключен на 1.

Кроме того, я не уверен, как это ведет себя при выполнении параллельных запросов. Если мы обновим две эти строки одновременно, возможно ли, что они будут возвращать одинаковые remaining_count?

Есть ли более элегантное решение для этого? Возможно, какая-то оконная / агрегатная функция?

1 Ответ

0 голосов
/ 10 ноября 2018

Подзапрос действительно выполняется, не видя изменений от UPDATE, потому что он выполняется до того, как UPDATE зафиксировал, и, следовательно, он не виден. Тем не менее, это легко исправить; просто добавьте предложение where, чтобы отфильтровать идентификатор, который вы только что обновили в подзапросе, сделав ваш запрос примерно таким:

UPDATE t AS updated SET state = 1
FROM t as original
WHERE 
    updated.id = original.id AND
    updated.id = :some_id
RETURNING
    updated.state AS new_state,
    original.state AS old_state,
    (
        SELECT COUNT(*) FROM t 
        WHERE 
            group_name = updated.group_name AND
            state = 0 AND
            t.id <> :some_id /* this is what I changed */
    ) as remaining_count;

В отношении параллелизма, я не уверен, каково будет поведение, TBH; лучшее, что я могу сделать, это указать вам соответствующие документы .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...