![](/img/trans.png)
[英]Mysql: Check if user have not been logged in last 14, 60 or 120 days
[英]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.