Składnia MySQL dla Join Update

83

Mam dwa stoły, które wyglądają tak

Pociąg

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

Rezerwacje

+---------------+-------------+------+-----+---------+----------------+
| 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    |                |
+---------------+-------------+------+-----+---------+----------------+

Obecnie próbuję utworzyć zapytanie, które zwiększy pojemność pociągu, jeśli rezerwacja zostanie anulowana. Wiem, że muszę wykonać dołączenie, ale nie jestem pewien, jak to zrobić w instrukcji aktualizacji. Na przykład wiem, jak uzyskać pojemność pociągu z danym identyfikatorem rezerwacji, na przykład:

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

Ale chciałbym utworzyć zapytanie, które to robi -

Increment Train.Capacity by ReservationTable.NoSeats given a ReservationID

Jeśli to możliwe, chciałbym również wiedzieć, jak zwiększyć o dowolną liczbę miejsc. Na marginesie, planuję usunąć rezerwację po wykonaniu przyrostu w transakcji Java. Czy usunięcie wpłynie na transakcję?

Dzięki za pomoc!

larjudge
źródło
2
Wiem, że to jest post sprzed 9 lat, ale w przypadku czegoś takiego jak przepustowość pociągu nie chcesz aktualizować kolumny z tego powodu, chyba że masz naprawdę dobry powód. Jak zauważyłeś, jest to pojedyncze złączenie. To jest coś, co zaktualizuje DUŻO - na rezerwację, więc powinno to być zapytanie wybierające w locie z dołączeniem, a nie aktualizacją. Nadmierne aktualizacje blokują tabele.
Jonathan

Odpowiedzi:

166

MySQL obsługuje składnię wielu tabelUPDATE , która wyglądałaby mniej więcej tak:

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

Możesz zaktualizować Traintabelę i usunąć ją z Reservationstabeli w tej samej transakcji. Tak długo, jak najpierw wykonujesz aktualizację, a następnie usuwasz jako drugą, powinno działać.

Bill Karwin
źródło
3
Bah, przez pomyłkę wstawiłem SETprzed JOIN. NB ludzie
deed02392
5

Oto kolejny przykład instrukcji UPDATE, która zawiera łączenia w celu określenia aktualizowanej wartości. W tym przypadku chcę zaktualizować transaction.payee_id o powiązany identyfikator płatności na koncie, jeśli payee_id wynosi zero (nie został przypisany).

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
źródło
Jeśli możesz się zastanawiać, jakie znaczenie ma 2nd JOIN do konta (alias jako ap), to dlatego, że najpierw napisałem zapytanie jako SELECT (co jest zawsze dobrą praktyką) przed konwersją na instrukcję UPDATE.
user3232196