簡體   English   中英

每位用戶最近60天的MySQL計算連勝記錄

[英]Mysql calculating streak per user last 60 days

我想從該mysql表計算60天內每個用戶的最長“條紋”。 條紋表示當天有一個供用戶輸入的條目。

+-----+------------+---------------------+
| id  | user       | date                |
+-----+------------+---------------------+
|   3 | test1      | 2014-06-10 23:55:01 |
|   4 | test2      | 2014-06-10 02:01:06 |
|   5 | test1      | 2014-06-11 23:55:06 |
|   6 | test2      | 2014-06-11 23:55:07 |
|   7 | test1      | 2014-06-12 23:55:07 |
|   9 | test1      | 2014-06-13 23:55:07 |
|   10| test2      | 2014-06-13 23:55:07 |

輸出應如下所示:

test1  4
test2  2 no entry on  2014-06-12

但我不知道如何正確執行此操作。

一種方法是使用MySQL用戶變量。 對於大集合,這不一定是最有效的方法,因為它實現了兩個內聯視圖。

SELECT s.user
     , MAX(s.streak) AS longest_streak
  FROM ( SELECT IF(@prev_user = o.user AND o.date = @prev_date + INTERVAL 1 DAY
                  , @streak := @streak + 1
                  , @streak := 1
                ) AS streak
              , @prev_user := o.user AS user
              , @prev_date := o.date AS `date`
           FROM ( SELECT t.user
                       , DATE(t.date) AS `date`
                    FROM mytable t
                   CROSS
                    JOIN (SELECT @prev_user := NULL, @prev_date := NULL, @streak := 1) i
                   WHERE t.date >= DATE(NOW()) + INTERVAL -60 DAY
                   GROUP BY t.user, DATE(t.date)
                   ORDER BY t.user, DATE(t.date)
                ) o
       ) s
 GROUP BY s.user

內聯視圖是別名,因為只是初始化了一些用戶變量; 我們實際上並不關心它返回的內容,只是由於JOIN操作,我們需要它返回精確的1行。 我們只關心在語句執行的早期初始化用戶變量的副作用。

別名為o的內聯視圖獲取用戶和日期的列表; 規范是針對“每個日期”的條目的,因此我們可以截斷時間部分,只獲取DATE,然后使用GROUP BY子句將其分成不同的集合。

別名為s的內聯視圖處理每一行,並將當前行的值保存到@prev_用戶變量中。 在覆蓋值之前,它會將當前行中的值與上一行中的值(已保存)進行比較。 如果用戶匹配,並且當前行上的日期比上一個日期晚1天,我們將繼續執行“連勝”,因此我們將@streak變量的當前值增加1。否則,上一個連勝為損壞,我們開始一個新的“條紋”,將@streak重置為1。

最后,我們處理s中的行以提取每個用戶的最大條紋。

(此聲明僅在桌面檢查,可能有兩個或兩個錯字。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM