Postgres обновлять столбец, только если столбец с таким же значением не существует - PullRequest
1 голос
/ 03 апреля 2020

Мне нужно выполнить простую операцию обновления для некоторых столбцов таблицы соединения в моей БД, однако я не хочу выполнять обновление, если столбец с обновленным значением уже существует.

Так скажем таблица соединения выглядит примерно так:

_id | fkId
----------
1   | A
1   | B
2   | B
3   | C
3   | B
4   | A
  • Я хочу обновить все записи, которые имеют fkId из B, до A
  • Однако, каждая запись должна быть уникальной, поэтому, если у меня уже есть другая запись для того же _id, уже установленная в fkId A, то я не хочу обновлять ее, а просто избавлюсь от нее

Мое обновление в настоящее время выглядит следующим образом:

  UPDATE my_table
  SET "fkId"='A'
  WHERE "fkId"='B';

В приведенной выше таблице примеров вы видите запись _id 1, поэтому, если я выполню этот запрос, я получу два записи как

_id | fkId
----------
1   | A
1   | A

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

1 Ответ

1 голос
/ 04 апреля 2020

Используйте условие not exists дополнительно:

UPDATE my_table AS t
  SET "fkId"='A'
  WHERE "fkId"='B' AND NOT EXISTS (
    SELECT 1 from my_table WHERE _id=t._id AND "fkId" = 'A');

Затем, если вы хотите удалить строки, которые не были обновлены - просто сделайте это:

DELETE FROM my_table WHERE "fkId" = 'B';

Чтобы избежать вмешательства из параллельных сеансов между этими двумя запросами вам, вероятно, нужно заблокировать строки раньше:

SELECT * FROM my_table WHERE "fkId" = 'B' FOR UPDATE;

Таким образом, вся ваша последовательность операторов может быть:

BEGIN;
SELECT * FROM my_table WHERE "fkId" = 'B' FOR UPDATE;
UPDATE my_table AS t
  SET "fkId"='A'
  WHERE "fkId"='B' AND NOT EXISTS (
    SELECT 1 from my_table WHERE _id=t._id AND "fkId" = 'A');
DELETE FROM my_table WHERE "fkId" = 'B';
COMMIT;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...