Haz todo lo posible por interpretar el código de forma correcta antes de aplicarlo a tu trabajo si ttienes algo que aportar puedes decirlo en los comentarios.
Solución:
Quizás una solución más simple para usted y evita que la base de datos tenga que hacer un montón de consultas. Esto ejecuta solo una consulta y luego hace un poco de matemática sobre los resultados en un solo paso.
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
Esto le dará una columna RT (total acumulado) adicional. No se pierda la declaración SET en la parte superior para inicializar primero la variable total acumulada o simplemente obtendrá una columna de valores 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
Esto requerirá algunos ajustes sintácticos (no tengo MySQL para probarlo), pero te muestra la idea. La subconsulta solo tiene que regresar y agregar todo lo nuevo que ya incluyó en la consulta externa, y tiene que hacer eso para cada fila.
Eche un vistazo a esta pregunta para saber cómo usar las uniones para lograr lo mismo.
Para abordar las preocupaciones sobre la degradación del rendimiento con datos en crecimiento: dado que hay máx. 366 días en un año, y asumo que no está ejecutando esta consulta en varios años, la subconsulta se evaluará hasta 366 veces. Con los índices adecuados en la fecha y la marca hasPaid, estarás bien.
A partir de MySQL 8, utilizará funciones de ventana para este tipo de consulta:
SELECT dayofyear(`date`) AS d, count(*), sum(count(*)) OVER (ORDER BY dayofyear(`date`))
FROM `orders`
WHERE `hasPaid` > 0
GROUP BY d
ORDER BY d
En la consulta anterior, la función agregada count(*)
está anidado dentro de la función de ventana sum(..) OVER (..)
, lo cual es posible debido al orden lógico de las operaciones en SQL. Si eso es demasiado confuso, puede recurrir fácilmente al uso de una tabla derivada o un WITH
cláusula para estructurar mejor su consulta:
WITH daily (d, c) AS (
SELECT dayofyear(`date`) AS d, count(*)
FROM `orders`
WHERE `hasPaid` > 0
GROUP BY d
)
SELECT d, c, sum(c) OVER (ORDER BY d)
ORDER BY d