120 votes

Syntaxe MySQL pour Join Update

J'ai deux tableaux qui ressemblent à ceci

Train

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

Réservations

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

J'essaie actuellement de créer une requête qui incrémente la capacité d'un train si une réservation est annulée. Je sais que je dois effectuer une jointure, mais je ne sais pas comment le faire dans une instruction de mise à jour. Par exemple, je sais comment obtenir la capacité d'un train avec un certain ReservationID, comme suit :

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

Mais j'aimerais construire la requête qui fait ça -

Increment Train.Capacity by ReservationTable.NoSeats given a ReservationID

Si possible, j'aimerais aussi savoir comment incrémenter par un nombre arbitraire de sièges. Par ailleurs, j'ai l'intention de supprimer la réservation après avoir effectué l'incrémentation dans une transaction Java. La suppression aura-t-elle un effet sur la transaction ?

Merci pour votre aide !

3 votes

Je sais que ce message date d'il y a 9 ans, mais pour quelque chose comme la capacité des trains, vous ne voulez pas mettre à jour une colonne pour cela, sauf si vous avez une très bonne raison. Comme vous l'avez souligné, il s'agit d'une jointure unique. C'est quelque chose qui va se mettre à jour BEAUCOUP - par réservation, donc cela devrait être une requête de sélection à la volée avec jointure, plutôt qu'une mise à jour. Les mises à jour excessives verrouillent les tables.

225voto

Bill Karwin Points 204877

MySQL prend en charge un multi-table UPDATE syntaxe qui ressemblerait approximativement à ceci :

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

Vous pouvez mettre à jour le Train et supprimer de la table Reservations dans la même transaction. Tant que vous effectuez la mise à jour en premier et la suppression en second, cela devrait fonctionner.

3 votes

Bah, j'ai mis le SET avant le JOIN par erreur. Les gens du NB

0 votes

Si vous êtes en mode sécurisé MySQL (par défaut), vous pouvez alors utiliser WHERE alias.primary_key_id > 0 pour contourner efficacement le mode sans échec et mettre à jour toutes les rangées.

9voto

user3232196 Points 129

Voici un autre exemple d'instruction UPDATE qui contient des jointures pour déterminer la valeur qui est mise à jour. Dans ce cas, je veux mettre à jour transactions.payee_id avec l'identifiant de paiement du compte correspondant, si le payee_id est égal à zéro (n'a pas été attribué).

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

0 votes

Si vous vous demandez quelle est la signification du second JOIN to account (alias ap), c'est simplement parce que j'ai d'abord écrit la requête comme un SELECT (ce qui est toujours une bonne pratique) avant de la convertir en déclaration UPDATE.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X