2016-10-01 366 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