J’ai une table qui ressemble à ceci:
id count 1 100 2 50 3 10
Je veux append une nouvelle colonne appelée cumulative_sum, pour que la table ressemble à ceci:
id count cumulative_sum 1 100 100 2 50 150 3 10 160
Existe-t-il une déclaration de mise à jour de MySQL qui peut le faire facilement? Quelle est la meilleure façon d’y parvenir?
Si les performances posent problème, vous pouvez utiliser une variable MySQL:
set @csum := 0; update YourTable set cumulative_sum = (@csum := @csum + count) order by id;
Vous pouvez également supprimer la colonne cumulative_sum
et la calculer sur chaque requête:
set @csum := 0; select id, count, (@csum := @csum + count) as cumulative_sum from YourTable order by id;
Cela calcule la sum en cours d’exécution d’une manière courante 🙂
SELECT t.id, t.count, (SELECT SUM(x.count) FROM TABLE x WHERE x.id <= t.id) AS cumulative_sum FROM TABLE t ORDER BY t.id
SELECT t.id, t.count, @running_total := @running_total + t.count AS cumulative_sum FROM TABLE t JOIN (SELECT @running_total := 0) r ORDER BY t.id
Remarque:
JOIN (SELECT @running_total := 0) r
est une jointure croisée et permet la déclaration de variables sans nécessiter de commande SET
distincte. r
, est requirejs par MySQL pour toute sous-requête / table dérivée / vue en ligne Mises en garde:
ORDER BY
est important; il s'assure que l'ordre correspond à l'OP et peut avoir des implications plus importantes pour une utilisation plus compliquée des variables (IE: fonctionnalité ROW_NUMBER / RANK de psuedo, qui manque à MySQL) UPDATE t SET cumulative_sum = ( SELECT SUM(x.count) FROM tx WHERE x.id <= t.id )
Exemple de requête
SET @runtot:=0; SELECT q1.d, q1.c, (@runtot := @runtot + q1.c) AS rt FROM (SELECT DAYOFYEAR(date) AS d, COUNT(*) AS c FROM orders WHERE hasPaid > 0 GROUP BY d ORDER BY d) AS q1
Vous pouvez également créer un déclencheur qui calculera la sum avant chaque insertion
delimiter | CREATE TRIGGER calCumluativeSum BEFORE INSERT ON someTable FOR EACH ROW BEGIN SET cumulative_sum = ( SELECT SUM(x.count) FROM someTable x WHERE x.id <= NEW.id ) set NEW.cumulative_sum = cumulative_sum; END; |
Je n'ai pas testé cela
select Id, Count, @total := @total + Count as cumulative_sum from YourTable, (Select @total := 0) as total ;