mysql如何進行累加計算

前言

接了一個需求,產品想分析一下用戶增加的曲線。也就是某個時間段的每日總人數列表。好對近期活動進行一個效果的評測。這個統計sql仍是花了我一小段時間的。mysql統計這個仍是須要必定的技巧的。java

需求分析

user_id reg_time
1 2019-09-03
2 2019-09-04
3 2019-09-04
4 2019-09-05
5 2019-09-05
6 2019-09-06

假如上表user_info,咱們很容易根據時間維度統計出每日新增的人數。sql以下:mysql

select reg_time, count(user_id) daily_quantity
  from user_info
group by reg_time

經過上面的sql咱們很容易得出如下列表:sql

reg_time daily_quantity
2019-09-03 1
2019-09-04 2
2019-09-05 2
2019-09-06 1

可是這個並非咱們想要的結果。咱們想要的應該是 上一天的總人數加上今天的淨增加數,以此類推。也就是咱們想要:數據庫

reg_time daily_quantity
2019-09-03 1
2019-09-04 3
2019-09-05 5
2019-09-06 6

這就有點棘手了,咱們須要進行累加計算。我嘗試了自連接,函數等一些操做後仍是沒有獲得一個正確的結果。這時想到若是是java代碼處理這個就再合適不過了,咱們只要聲明初始值,而後循環累加就能計算出結果了:函數

public static void main(String[] args) {
        int[] arr = {1, 2, 2, 1};

        int[] ints = dailyQuantityArr(0, arr);


        for (int i : ints) {
            System.out.println("i = " + i);
        }


    }


    public static int[] dailyQuantityArr(int base, int[] dailyIncrQuantity) {


        int[] result = new int[dailyIncrQuantity.length];
        // 累加填充
        for (int i = 0; i < dailyIncrQuantity.length; i++) {
            base += dailyIncrQuantity[i];

            result[i] = base;

        }
        return result;
    }

上面的僞代碼就能夠計算出結果。固然若是能夠的話儘可能在java業務代碼進行這種複雜運算。可是產品給出的需求是咱們可以提供一句sql可以直接在可視化數據引擎中得出他要的答案。因而從上面的代碼得出靈感。
mysql是否有這種變量呢? 有!固然有。記得很廣泛的場景,之前常常有業務須要咱們輸出序號,Oracle是自帶一個僞列rownum,可是mysql沒有。mysql一般經過聲明自增變量來生成序號。拿user_info表舉例子:學習

select (@i:=@i+1) as rownum, user_id 
   from user_info ,(select @i:=0) as r

Mysql 用戶變量

mysql 變量分爲 局部變量、用戶變量、會話變量、全局變量 。上面的語句咱們使用的是用戶變量。用戶變量與數據庫鏈接有關,在鏈接中聲明的變量,在存儲過程當中建立了用戶變量後一直到數據庫實例接斷開的時候,變量就會消失。在此鏈接中聲明的變量沒法在另外一鏈接中使用。
MySQL中用戶變量不用事前申明,使用的時候以@varname的格式進行聲明。經過:=或者=進行賦值操做。若是須要對外輸出須要用select關鍵字,並且賦值必須使用:=編碼

使用Mysql用戶變量進行累加計算

咱們學習了用戶變量後就知道如何進行累加計算了,那麼user_info表的日累計總人數應該是這樣的:spa

select a.reg_time,
             a.daily,
          @i:=@i+a.daily as daily_quantity  
        from (select reg_time ,        
        count(user_id) daily 
        from user  group by  reg_time ) a ,
       (select @i:=0) b

查詢的結果以下,符合邏輯須要。code

reg_time daily daily_quantity
2019-09-03 1 1
2019-09-04 2 3
2019-09-05 2 5
2019-09-06 1 6

可是這裏有一個小坑,在實際業務中@i初始化的時候有可能不爲0,好比咱們統計上面9月4號到9月6號這時候以前的總人數爲1 。 這個要特別注意。實際業務開發中若是咱們能在邏輯編碼中實現仍是建議在邏輯編碼中進行一些複雜的運算。開發

總結

今天咱們經過mysql用戶變量解決了一個在sql中累加計算的問題。不知道你有沒有其它好的思路呢?歡迎留言討論。

關注公衆號:碼農小胖哥 獲取更多資訊

相關文章
相關標籤/搜索