上次遇到一個需求是統計流失與迴流用戶。流失用戶分爲7日流失、14日流失、30日流失,n日流失的定義爲到統計日期爲止,連續n日沒有遊戲記錄的用戶即爲統計日期當天的n日流失;迴流用戶也分爲7日迴流、14日迴流、30日迴流,n日迴流的定義爲在統計日期有遊戲記錄,在統計日期以前的最近一次遊戲記錄距離統計日期大於等於n日即爲統計日期當天的n日迴流。當時聽產品經理闡述需求的時候就有一點一臉懵逼,不過理解以後就還好了,能夠參照下圖。sql
n日流失定義:code
n日迴流定義:blog
目前有一個日表記錄着每一個用戶天天的局數,表結構以下:遊戲
表中的數據以下:產品
假設如今咱們想要統計在2018.7.10的n日流失用戶有哪些,咱們能夠這樣來查詢:class
SELECT user_id FROM ( SELECT * FROM user_day A WHERE NOT EXISTS ( SELECT 1 FROM user_day WHERE user_id = A .user_id AND log_date > A .log_date AND log_date <= '2018-07-10' ) AND A .log_date <= '2018-07-10' ) AS b WHERE log_date = '2018-07-03';
其中子查詢的做用是篩選出每一個用戶在小於等於2018-07-10日的最近的一條遊戲記錄,而後在其中篩選出在2018-07-03日的遊戲記錄對應的用戶ID,這些用戶ID對應的用戶即爲2018-07-10日的7日流失用戶。date
假設咱們想要統計在2018-07-10的7日迴流用戶的話,能夠這樣來查詢:im
SELECT user_id FROM ( SELECT user_id, log_date FROM user_day u WHERE NOT EXISTS ( SELECT * FROM user_day WHERE user_id = u.user_id AND log_date > u.log_date AND log_date < '2018-07-10' ) AND u.log_date < '2018-07-10' ) AS A WHERE log_date <= '2018-07-03' AND user_id IN ( SELECT user_id FROM user_day WHERE log_date = '2018-07-10' );
其中子查詢的做用是篩選出每一個用戶在小於2018-07-10日的最近的一條遊戲記錄,而後在其中篩選出小於2018-07-03日的遊戲記錄對應的user_id,而後在查詢這些user_id中在2018-07-10日有遊戲記錄的user_id,即爲2018-07-10日的7日迴流用戶ID。統計