2016-10-01 367 views
2

我的目标是获得按日期注册用户的累积数量mysql sql:如何累计数量? (计数的总和)

这里是我的MySQL SQL

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

这让我每月的用户数量,但也没有积蓄他们

结果:

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

我想:

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` 
    ); 

,并得到了错误:#1248 - 每一个派生表必须有它自己的别名

+0

检查我发布的答案... – Teja

+0

我不认为上述重复将有助于此OP,因为它不涉及聚合。 –

回答

2

在MySQL中,基本上有三种方式累计总和:

  • 相关子查询。
  • 不平等加入聚合。
  • 变量。

后者是最简单的。然而,由于该方式group by作品在MySQL中,往往需要一个子查询:

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; 

注:

  • 这需要明智地在今年考虑。当你按月累计时,通常会这样做。
  • 在查询中定义了@sum变量。这是一个方便。
  • 子查询是必需的,因为有时候变量不能按照预期的方式与聚合一起工作。
  • 该子查询有一个别名。
0
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` 
    ); 

另一种解决方案: -

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

什么是:(按月排列的无界前沿和当前行)?这是一个评论? – yarek

+0

无界前导和当前行之间的行是一种sql语法,您可以在当前行之前对所有行执行计算。 – Teja

+0

#1064 - 您的SQL语法错误;检查对应于您的MySQL服务器版本的手册,以便在第二行使用正确的语法'(ORDER BY month ROWS BETWEEN UNBOUNDED PRECEEDING AN'at line 2 – yarek

0

在MySQL中,你可以利用会话变量的。如下所示:

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

否则,您将不得不加入两个表格,但这样做效率不高。

0

尝试的东西,如:

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` 

感谢JPW整改

+1

如果您将子查询中的where子句更改为WHERE userid = 1 AND MONTH(DATE)<= MONTH(s.DATE),那么您的查询应产生预期结果。 – jpw