Calcola un totale parziale in MySQL

Ho questa query MySQL:

SELECT DAYOFYEAR(`date`) AS d, COUNT(*) FROM `orders` WHERE `hasPaid` > 0 GROUP BY d ORDER BY d 

Che restituisce qualcosa del genere:

 d | COUNT(*) | 20 | 5 | 21 | 7 | 22 | 12 | 23 | 4 | 

Quello che mi piacerebbe davvero è un’altra colonna alla fine per mostrare il totale parziale:

 d | COUNT(*) | ??? | 20 | 5 | 5 | 21 | 7 | 12 | 22 | 12 | 24 | 23 | 4 | 28 | 

È ansible?

Forse una soluzione più semplice per te e impedisce al database di fare un sacco di domande. Questo esegue solo una query quindi esegue un po ‘di matematica sui risultati in un singolo passaggio.

 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 

Questo ti darà una colonna aggiuntiva RT (totale parziale). Non perdere l’istruzione SET in alto per inizializzare la variabile totale parziale o otterrai una colonna di valori NULL.

 SELECT DAYOFYEAR(O.`date`) AS d, COUNT(*), (select count(*) from `orders` where DAYOFYEAR(`date`) < = d and `hasPaid` > 0) FROM `orders` as O WHERE O.`hasPaid` > 0 GROUP BY d ORDER BY d 

Ciò richiederà alcune sintonizzazioni sintattiche (non ho MySQL per testarlo), ma ti mostra l’idea. La subquery deve solo tornare indietro e aggiungere tutto ciò che è già incluso nella query esterna, e deve farlo per ogni riga.

Dai un’occhiata a questa domanda su come utilizzare i join per ottenere lo stesso risultato.

Per affrontare le preoccupazioni sul degrado delle prestazioni con i dati in crescita: poiché ci sono max. 366 giorni in un anno e presumo che non si stia eseguendo questa query per più anni, la sottoquery verrà valutata fino a 366 volte. Con gli indici appropriati alla data e al flag hasPaid, sarai a posto.

Direi che è imansible che ogni riga risultante sia indipendente. Usa il linguaggio di programmazione per ottenere questi valori

A meno che tu non abbia altra opzione che fare questo in sql, sommerei i risultati nel linguaggio di programmazione che sta facendo la query. Un nido come questo diventerà molto lento man mano che la tabella cresce.

Puoi modificarlo usando l’istruzione Cross Join o alcuni join slef ma diventerà lento con qualsiasi set di dati di grandi dimensioni, quindi probabilmente è meglio farlo in un processore di query post; o cursore del codice cliente

Questo è uno degli unici posti in cui i cursori sono più veloci di una query basata su set, anche se le prestazioni sono critiche

  • Fai questo al di fuori di MySql o
  • Utilizzare MySql 5 Cursors