mysql sql

order by mysql



Calcule un total acumulado en MySQL (6)

A menos que no tenga otra opción que hacer esto en sql, sumaría los resultados en el lenguaje de programación que está haciendo la consulta. Un anidamiento como este se volverá muy lento a medida que la mesa crezca.

Tengo esta consulta MySQL:

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

Que devuelve algo como esto:

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

Lo que realmente me gustaría es otra columna al final para mostrar el total acumulado:

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

es posible?


Diría que es imposible que cada fila resultante sea independiente. Use el lenguaje de programación para obtener estos valores


Este es uno de los únicos lugares donde los cursores son más rápidos que las consultas basadas en conjuntos, si el rendimiento es crítico, cualquiera

  • Haz esto fuera de MySql o
  • Utilice los cursores de MySql 5

Puede hackear esto usando la instrucción Cross Join o algunas combinaciones de slef, pero se ralentizará con cualquier conjunto de datos de gran tamaño, por lo que probablemente sea mejor hacerlo en un procesador posterior a la consulta; cualquiera cursor de en el código del cliente


Tal vez sea 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 una sola pasada.

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 adicional (total acumulado). No se pierda la instrucción SET en la parte superior para inicializar primero la variable total en ejecución o simplemente obtendrá una columna de valores NULOS.


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á un ajuste sintáctico (no tengo MySQL para probarlo), pero te muestra la idea. La subconsulta solo tiene que volver 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 sobre cómo usar uniones para lograr lo mismo.

Para abordar las preocupaciones sobre la degradación del rendimiento con datos crecientes: ya que hay max. 366 días en un año, y supongo 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 bandera hasPaid, estarás bien.