Синтаксис MySQL для обновления присоединения

84

У меня есть две таблицы, которые выглядят так

Поезд

+----------+-------------+------+-----+---------+-------+
| Field    | Type        | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| TrainID  | varchar(11) | NO   | PRI | NULL    |       |
| Capacity | int(11)     | NO   |     | 50      |       |
+----------+-------------+------+-----+---------+-------+

Бронирование

+---------------+-------------+------+-----+---------+----------------+
| Field         | Type        | Null | Key | Default | Extra          |
+---------------+-------------+------+-----+---------+----------------+
| ReservationID | int(11)     | NO   | PRI | NULL    | auto_increment |
| FirstName     | varchar(30) | NO   |     | NULL    |                |
| LastName      | varchar(30) | NO   |     | NULL    |                |
| DDate         | date        | NO   |     | NULL    |                |
| NoSeats       | int(2)      | NO   |     | NULL    |                |
| Route         | varchar(11) | NO   |     | NULL    |                |
| Train         | varchar(11) | NO   |     | NULL    |                |
+---------------+-------------+------+-----+---------+----------------+

В настоящее время я пытаюсь создать запрос, который увеличит емкость поезда, если бронирование отменено. Я знаю, что мне нужно выполнить соединение, но я не уверен, как это сделать в операторе обновления. Например, я знаю, как получить пропускную способность поезда с заданным идентификатором ReservationID, например:

select Capacity 
  from Train 
  Join Reservations on Train.TrainID = Reservations.Train 
 where ReservationID = "15";

Но я хотел бы создать запрос, который делает это -

Increment Train.Capacity by ReservationTable.NoSeats given a ReservationID

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

Спасибо за помощь!

судья
источник
2
Я знаю, что это пост 9-летней давности, но для чего-то вроде пропускной способности поездов вы не хотите обновлять столбец для этого, если у вас нет действительно веской причины. Как вы отметили, это одно соединение. Это то, что будет обновлять МНОГОЕ - за резервирование, поэтому это должен быть запрос выбора на лету с объединением, а не обновление. Чрезмерные обновления блокируют таблицы.
Джонатан

Ответы:

166

MySQL поддерживает многотабличный UPDATEсинтаксис , который будет выглядеть примерно так:

UPDATE Reservations r JOIN Train t ON (r.Train = t.TrainID)
SET t.Capacity = t.Capacity + r.NoSeats
WHERE r.ReservationID = ?;

Вы можете обновить Trainтаблицу и удалить из Reservationsнее в той же транзакции. Если вы сначала выполняете обновление, а затем выполняете удаление, он должен работать.

Билл Карвин
источник
3
Ба, я по ошибке поставил SETперед JOIN. NB, народ
deed02392
5

Вот еще один пример оператора UPDATE, который содержит соединения для определения обновляемого значения. В этом случае я хочу обновить transaction.payee_id соответствующим идентификатором платежа учетной записи, если payee_id равно нулю (не было назначено).

UPDATE transactions t
  JOIN account a ON a.id = t.account_id
  JOIN account ap ON ap.id = a.pmt_act_id
  SET  t.payee_id = a.pmt_act_id
 WHERE t.payee_id = 0
user3232196
источник
Если вам может быть интересно, каково значение второго JOIN для учетной записи (с псевдонимом ap), это произошло потому, что я сначала написал запрос как SELECT (что всегда является хорошей практикой) перед преобразованием в оператор UPDATE.
user3232196