sql — обновление строк таблицы в postgres с помощью подзапроса
Есть много способов обновить строки.
Когда дело доходит до UPDATE
строк с использованием подзапросов, вы можете использовать любой из этих подходов.
- Подход-1 [Использование прямой ссылки на таблицу]
ОБНОВЛЕНИЕ <таблица1> УСТАНОВЛЕН клиент=<таблица2>.клиент, адрес=<таблица2>.адрес, partn=<таблица2>.partn ИЗ <таблица2> КУДА <таблица1>.address_id=<таблица2>.address_i;
Объяснение:
таблица1
— это таблица, которую мы хотим обновить,таблица2
это таблица, из которой мы будем получать значение для замены/обновления. Мы используем предложениеFROM
для получения данныхtable2
.ГДЕ
Предложение поможет установить правильное отображение данных.
- Подход-2 [Использование подзапросов]
ОБНОВЛЕНИЕ <таблица1> УСТАНОВЛЕН клиент=подзапрос.клиент, адрес=подзапрос.адрес, partn=subquery.partn ИЗ ( ВЫБРАТЬ address_id, клиент, адрес, партнер FROM /* большой волосатый SQL */ ... ) AS подзапрос КУДА dummy.address_id = подзапрос.address_id;
Объяснение: Здесь мы используем подзапрос внутри предложения
FROM
, и дать ему псевдоним. Так что он будет действовать как стол.
- Подход-3 [Использование нескольких объединенных таблиц]
ОБНОВЛЕНИЕ <таблица1> УСТАНОВЛЕН клиент=<таблица2>.клиент, адрес=<таблица2>.адрес, partn=<таблица2>.partn ИЗ <таблица2> как t2 ПРИСОЕДИНЯЙТЕСЬ ккак t3 НА t2.id = t3.id КУДА <таблица1>.address_id=<таблица2>.address_i;
Объяснение: Иногда мы сталкиваемся с ситуацией, что объединение таблиц так важно получить правильные данные для обновления. Для этого Postgres позволяет нам присоединиться к нескольким таблицам внутри предложения
FROM
.
- Подход-4 [Использование оператора WITH]
- 4.1 [Использование простого запроса]
С подзапросом AS ( ВЫБРАТЬ адрес_идентификатор, покупатель, адрес, партнер ИЗ <таблица1>; ) ОБНОВЛЕНИЕ <таблица-X> SET клиент = подзапрос.клиент, адрес = подзапрос.адрес, часть = подзапрос.partn ИЗ подзапроса ГДЕ <таблица-X>.address_id = subquery.address_id;
- 4.2 [Использование запроса со сложным JOIN]
С подзапросом AS ( ВЫБЕРИТЕ address_id, клиент, адрес, партнер ИЗ <таблица1> как t1 ПРИСОЕДИНИТЬСЯ <таблица2> как t2 НА t1.id = t2.id; -- Вы можете построить как СЛОЖНЫЙ, как этот запрос в соответствии с вашими потребностями. ) ОБНОВЛЕНИЕ <таблица-X> SET клиент = подзапрос.клиент, адрес = подзапрос.адрес, часть = подзапрос.partn ИЗ подзапроса ГДЕ <таблица-X>.address_id = subquery.address_id;
Объяснение. Начиная с Postgres 9.1, эта концепция (
WITH
) была представил. Используя это, мы можем делать любые сложные запросы и генерировать желаемый результат. Здесь мы используем этот подход для обновления таблицы.
Надеюсь, это будет полезно..😊
postgresql — обновление postgres после выбора
В общем, вы должны сделать это с помощью одного оператора UPDATE. На UPDATE обычно не влияют строки, которые могли быть изменены во время выполнения оператора UPDATE, однако полезно прочитать об уровнях изоляции транзакций здесь.
Предполагая, что вы используете значение по умолчанию Read Committed, вот что он говорит:
Read Committed — это уровень изоляции по умолчанию в PostgreSQL. Когда транзакция выполняется на этом уровне изоляции, запрос SELECT видит только данные зафиксированы до начала запроса;
Что касается ОБНОВЛЕНИЯ:
Команды UPDATE, DELETE, SELECT FOR UPDATE и SELECT FOR SHARE вести себя так же, как SELECT в плане поиска целевых строк: они найдет только целевые строки, которые были зафиксированы на момент запуска команды время. Однако такая целевая строка могла быть уже обновлена (или удалена или заблокирована) другой параллельной транзакцией к моменту ее найденный. В этом случае будущий апдейтер будет ждать первого обновление транзакции для фиксации или отката (если она все еще находится в прогресс). Если первое обновление откатывается, то его последствия отменяется, и второй модуль обновления может приступить к обновлению первоначально найденный ряд. Если первый модуль обновления фиксируется, второй модуль обновления проигнорирует строку, если первая программа обновления удалила ее, в противном случае она будет попытаться применить свою операцию к обновленной версии строки. условие поиска команды (предложение WHERE) переоценивается для посмотреть, соответствует ли обновленная версия строки поиску условие. Если это так, второй модуль обновления продолжает свою работу, начиная с обновленной версии ряда. (В случае выбора FOR UPDATE и SELECT FOR SHARE, это означает, что это обновленная версия строки, которая заблокирована и возвращена клиенту.
)
Итак, в вашем сценарии достаточно одного ОБНОВЛЕНИЯ.
Имейте также в виду, что существует оператор SELECT FOR UPDATE
, который блокирует выбранные вами строки. Вы можете прочитать об этом здесь.
Сценарий, в котором вам нужно будет использовать эту функцию, будет в системе бронирования. Рассмотрим следующий пример:
- Выполните
SELECT
, чтобы узнать, свободна ли комната XYZ для бронирования на дату X. - Комната свободна. Выполнить
ОБНОВЛЕНИЕ
запрос на бронирование номера.
Вы видите здесь потенциальную проблему? Если между шагами 1 и 2 комната забронирована другой транзакцией, то когда мы достигнем шага 2, мы будем действовать исходя из предположения, которое уже недействительно, а именно, что комната свободна.
Однако, если на шаге 1 вместо этого использовать оператор SELECT FOR UPDATE, мы гарантируем, что никакая другая транзакция не сможет заблокировать эту строку, поэтому, когда мы переходим к UPDATE строки, мы знаем, что это безопасно.