Créer une colonne de sum cumulative dans MySQL

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 🙂

En utilisant une requête corrélée:


  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 

Utiliser des variables MySQL:


  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.
  • L'alias de la table, r , est requirejs par MySQL pour toute sous-requête / table dérivée / vue en ligne

Mises en garde:

  • MySQL spécifique non portable à d'autres bases de données
  • L' 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 ;