/ / mysql sql: ¿cómo acumular recuento? (suma de conteo) - mysql, sql

mysql sql: ¿cómo acumular el recuento? (suma del recuento) - mysql, sql

Mi objetivo es conseguir el número acumulado de usuarios registrados por fecha.

Aquí está mi sql mysql

SELECT MONTH( DATE ) AS `month`, COUNT(userid)
FROM  `stats`
WHERE  `userid` = 1
GROUP BY `month`

Esto me da la cantidad de usuarios por mes, pero no los acumula

resultado:

month 1 : 90
month 2 : 50 (it should be 90 + 50)
month 3 : 10 (it should be 90 + 50 + 10)

Lo intenté:

SELECT month,
SUM( CNT ) AS CUM_CNT_TILL_NOW
FROM  (
SELECT MONTH( DATE ) AS `month`, COUNT(userid) AS CNT
FROM  `stats`
WHERE  `userid` = 1
GROUP BY `month`
);

y se obtuvo un error: # 1248 - Cada tabla derivada debe tener su propio alias

Respuestas

2 para la respuesta № 1

En MySQL, hay básicamente tres formas de hacer una suma acumulativa:

  • Una subconsulta correlacionada.
  • La desigualdad se une a la agregación.
  • Variables.

Este último es el más sencillo. Sin embargo, debido a la forma en que group by Funciona en MySQL, a menudo necesitas una subconsulta:

SELECT yyyy, mm, cnt,
(@sum := @sum + cnt) as cume_sum
FROM (SELECT YEAR(DATE) as yyyy, MONTH( DATE ) AS mm, COUNT(userid) AS CNT
FROM stats
WHERE userid = 1
GROUP BY yyyy, mm
) ym CROSS JOIN
(SELECT @sum := 0) params
ORDER BY yyyy, mm;

Notas:

  • Esto sabiamente tiene en cuenta el año. Eso es usualmente destinado cuando estás acumulando por mes.
  • los @sum La variable se define en la consulta. Esto es una conveniencia.
  • La subconsulta es necesaria porque a veces las variables no funcionan como se esperaba con las agregaciones.
  • La subconsulta tiene un alias.

0 para la respuesta № 2

En Mysql, puedes hacer uso de la variable de sesión. como abajo:

SET @sum = 0;
SELECT MONTH( DATE ) AS `month`, @sum:=@sum+COUNT(userid) as sum
FROM  `stats`
WHERE  `userid` = 1
GROUP BY `month`;

O bien, tendrá que unir las dos tablas, pero eso sería ineficaz.


0 para la respuesta № 3
SELECT month,
SUM( CNT ) OVER ( ORDER BY month ROWS BETWEEN UNBOUNDED PRECEEDING
AND CURRENT ROW
) AS CUM_CNT_TILL_NOW
FROM
(
SELECT MONTH( DATE ) AS `month`, COUNT(userid) AS CNT
FROM  `stats`
WHERE  `userid` = 1
GROUP BY `month`
);

Otra solución :-

WITH tmp AS
(
SELECT MONTH( DATE ) AS `month`, COUNT(userid) AS CNT
FROM  `stats`
WHERE  `userid` = 1
GROUP BY `month`
)
SELECT o.month, o.cnt , RunningTotal = o.cnt + COALESCE(
(
SELECT SUM(cnt) AS cnt
FROM tmp i
WHERE i.month < o.month), 0
)
FROM tmp AS o
ORDER BY o.month;

0 para la respuesta № 4

prueba con algo como:

SELECT MONTH(DATE) AS `month`, COUNT(userid) , (SELECT COUNT(userid)
FROM  `stats`
WHERE  `userid` = 1 AND MONTH(date) <= MONTH(s.date))
FROM  `stats` s
WHERE  `userid` = 1
GROUP BY `month`

Gracias jpw por la corrección