Dire que j'ai les deux tables players
et stats
avec le contenu suivant:Accès à une colonne précédemment mis à jour dans la même requête se comporte différemment avec JOIN/updates multi-tables
mysql> select * from players;
+----+-------+
| id | alive |
+----+-------+
| 1 | 0 |
| 2 | 1 |
+----+-------+
mysql> select * from stats;
+--------+------+------+-------+
| player | win | lose | ratio |
+--------+------+------+-------+
| 1 | 12 | 20 | 0.6 |
| 2 | 8 | 1 | 8 |
+--------+------+------+-------+
Et je veux incrémenter win
-counter de chaque joueur, tout en mettant à jour leur rapport gagnant/perdant. Cela ressemblerait à quelque chose comme ceci:
update `stats` set `win` = `win` + 1, `ratio` = `win`/`lose`;
Notez que la valeur incrémentée de win
est utilisée pour calculer la ratio
(comme les états manuels de MySQL ici: 1.8.2.2 UPDATE Differences).
Maintenant, lorsqu'un JOIN est ajouté à l'UPDATE requête de le limiter aux joueurs que de mise à jour où alive = 1
, ce comportement change:
update `stats` st
inner join `players` pl
on (pl.`id` = st.`player`)
set `win` = `win` + 1, `ratio` = `win`/`lose`
where pl.`alive` = 1;
mysql> select * from stats;
+--------+------+------+-------+
| player | win | lose | ratio |
+--------+------+------+-------+
| 1 | 12 | 20 | 0.6 |
| 2 | 9 | 1 | 8 |
+--------+------+------+-------+
La seule solution que j'ai trouvé est d'attribuer la nouvelle valeur de win
à une variable temporaire et utiliser celui-ci lors du calcul du ratio
à la place:
update `stats` st
inner join `players` pl
on (pl.`id` = st.`player`)
set
`win` = @tmpWin := (`win` + 1),
`ratio` = @tmpWin/`lose`
where pl.`alive` = 1;
Pourquoi MySQL se comporte comme ça, et est-il une solution plus élégante à un probl em de ce genre (autre que de créer une vue pour calculer le ratio à la volée)?
Les tableaux ont été créés comme suit:
create table `players` (
`id` INT,
`alive` TINYINT,
primary key (`id`)
);
create table `stats` (
`player` INT,
`win` INT,
`lose` INT,
`ratio` FLOAT,
primary key (`player`)
);
J'utilise MySQL v5.7.17
Avec 5.7.17, vous pouvez utiliser [colonnes générées] (https://dev.mysql.com/doc/refman/5.7/en/create-table-generated-columns.html). –