Créer une colonne de Somme Cumulative dans MySQL

J'ai une table qui ressemble à ceci:

id   count
1    100
2    50
3    10

Je veux ajouter une nouvelle colonne appelée cumulative_sum, de sorte que la table ressemblerait à ceci:

id   count  cumulative_sum
1    100    100
2    50     150
3    10     160

Existe-t-il une instruction de mise à jour MySQL qui peut le faire facilement? Quelle est la meilleure façon d'accomplir cette?

57
demandé sur Bulat 2010-04-02 01:50:17

7 réponses

Si la performance est un 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 somme courante de manière courante:)

72
répondu Andomar 2010-04-01 22:08:26

Utilisation d'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

Utilisation 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:

  • le {[2] } est une jointure croisée, et permet une déclaration de variable sans nécessiter une commande SET séparée.
  • l'alias de table, r, est requis par MySQL pour toute sous-requête / table dérivée / vue en ligne

Mises en garde:

  • spécifique à MySQL; non portable à d'autres bases de données
  • le {[5] } est important; il assure l'ordre correspond à L'OP et peut avoir des implications plus importantes pour une utilisation de variables plus compliquée (C'est-à-dire: psuedo ROW_NUMBER/RANK fonctionnalité, qui manque à MySQL)
85
répondu OMG Ponies 2010-04-28 14:41:40
UPDATE t
SET cumulative_sum = (
 SELECT SUM(x.count)
 FROM t x
 WHERE x.id <= t.id
)
4
répondu Dercsár 2010-04-01 21:59:06

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
2
répondu Jazz 2011-07-04 12:04:05

MySQL 8.0 / MariaDB prend en charge fenêtré SUM(col) OVER():

SELECT *, SUM(cnt) OVER(ORDER BY id) AS cumulative_sum
FROM tab;

Sortie:

┌─────┬──────┬────────────────┐
│ id  │ cnt  │ cumulative_sum │
├─────┼──────┼────────────────┤
│  1  │ 100  │            100 │
│  2  │  50  │            150 │
│  3  │  10  │            160 │
└─────┴──────┴────────────────┘

Dbviolon

2
répondu Lukasz Szozda 2018-09-11 14:49:00

Vous pouvez également créer un déclencheur qui calculera la somme 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é

1
répondu Greg 2016-07-08 07:59:46
select Id, Count, @total := @total + Count as cumulative_sum
from YourTable, (Select @total := 0) as total ;
1
répondu Ashutosh SIngh 2017-02-13 14:41:13