SQL統(tǒng)計連續(xù)登陸3天用戶的實(shí)現(xiàn)示例
1. 數(shù)據(jù)準(zhǔn)備
-- 數(shù)據(jù)準(zhǔn)備 WITH user_active_info AS ( SELECT * FROM ( VALUES ('10001' , '2023-02-01'),('10001' , '2023-02-03') ,('10001' , '2023-02-04'),('10001' , '2023-02-05') ,('10002' , '2023-02-02'),('10002' , '2023-02-03') ,('10002' , '2023-02-04'),('10002' , '2023-02-05') ,('10002' , '2023-02-07'),('10003' , '2023-02-02') ,('10003' , '2023-02-03'),('10003' , '2023-02-04') ,('10003' , '2023-02-05'),('10003' , '2023-02-06') ,('10003' , '2023-02-07'),('10003' , '2023-02-08') ,('10004' , '2023-02-03'),('10004' , '2023-02-04') ,('10004' , '2023-02-06'),('10004' , '2023-02-07') ,('10004' , '2023-02-08'),('10004' , '2023-02-08') ,('10005' , '2023-02-02'),('10005' , '2023-02-05') ) AS user_active_info(user_id, active_date) )
2. 方法一: 差值計算
-- 1. 對用戶數(shù)據(jù)進(jìn)行分組,按照活躍日期進(jìn)行排序(去重:防止有一天有多次活躍記錄) SELECT user_id , active_date , ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY active_date) AS rn FROM user_active_info GROUP BY user_id , active_date ;
user_id | active_date | rn |
---|---|---|
10001 | 2023-02-01 | 1 |
10001 | 2023-02-03 | 2 |
10001 | 2023-02-04 | 3 |
10001 | 2023-02-05 | 4 |
10002 | 2023-02-02 | 1 |
10002 | 2023-02-03 | 2 |
10002 | 2023-02-04 | 3 |
10002 | 2023-02-05 | 4 |
10002 | 2023-02-07 | 5 |
… | … | … |
-- 2. 使用活躍日期和排序rn進(jìn)行差值計算,得到的日期如果是相等的,就說明活躍日期是連續(xù)的 SELECT user_id , active_date , rn , DATE_SUB(active_date,rn) AS sub_date FROM ( SELECT user_id , active_date , ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY active_date) AS rn FROM user_active_info GROUP BY user_id , active_date ) a ;
user_id | active_date | rn | sub_date |
---|---|---|---|
10001 | 2023-02-01 | 1 | 2023-01-31 |
10001 | 2023-02-03 | 2 | 2023-02-01 |
10001 | 2023-02-04 | 3 | 2023-02-01 |
10001 | 2023-02-05 | 4 | 2023-02-01 |
10002 | 2023-02-02 | 1 | 2023-02-01 |
10002 | 2023-02-03 | 2 | 2023-02-01 |
10002 | 2023-02-04 | 3 | 2023-02-01 |
10002 | 2023-02-05 | 4 | 2023-02-01 |
10002 | 2023-02-07 | 5 | 2023-02-02 |
… | … | … | … |
-- 3. 按照user_id和sub_date 進(jìn)行分組求和,篩選出連續(xù)登陸天數(shù)大于3天的用戶 SELECT user_id , MIN(active_date) AS begin_date , MAX(active_date) AS end_date , COUNT (1) AS login_duration FROM ( SELECT user_id , active_date , rn , DATE_SUB(active_date,rn) AS sub_date FROM ( SELECT user_id , active_date , ROW_NUMBER() OVER(PARTITION BY user_id ORDER BY active_date) AS rn FROM user_active_info GROUP BY user_id , active_date ) a ) b GROUP BY user_id , sub_date HAVING login_duration >= 3 ;
user_id | begin_date | end_date | login_duration |
---|---|---|---|
10001 | 2023-02-03 | 2023-02-05 | 3 |
10002 | 2023-02-02 | 2023-02-05 | 4 |
10003 | 2023-02-02 | 2023-02-08 | 7 |
10004 | 2023-02-06 | 2023-02-08 | 3 |
3. 方法二: lead或lag函數(shù)
-- 1. 將active_date 上抬2行,不存在默認(rèn)為'0'(計算連續(xù)活躍3天以上的, 上抬2行,n天上抬n-1行)(去重:防止有一天有多次活躍記錄) SELECT user_id , active_date , lead(active_date , 2 , 0) OVER(PARTITION BY user_id ORDER BY active_date) AS lead_active_date FROM user_active_info GROUP BY user_id , active_date
user_id | active_date | lead_active_date |
---|---|---|
10001 | 2023-02-01 | 2023-02-04 |
10001 | 2023-02-03 | 2023-02-05 |
10001 | 2023-02-04 | 0 |
10001 | 2023-02-05 | 0 |
10002 | 2023-02-02 | 2023-02-04 |
10002 | 2023-02-03 | 2023-02-05 |
10002 | 2023-02-04 | 2023-02-07 |
10002 | 2023-02-05 | 0 |
10002 | 2023-02-07 | 0 |
… | … | … |
-- 2. 過濾篩選出, lead_active_date 與 active_date 差值為2的, 差值2 -> 連續(xù)活躍了3天 SELECT user_id , active_date , lead_active_date FROM ( SELECT user_id , active_date , lead(active_date , 2 , 0) OVER(PARTITION BY user_id ORDER BY active_date) AS lead_active_date FROM user_active_info GROUP BY user_id , active_date ) a WHERE lead_active_date != '0' AND DATEDIFF(lead_active_date , active_date) = 2
user_id | active_date | lead_active_date |
---|---|---|
10001 | 2023-02-03 | 2023-02-05 |
10002 | 2023-02-02 | 2023-02-04 |
10002 | 2023-02-03 | 2023-02-05 |
… | … | … |
-- 3. user_id 去重, 得到連續(xù)活躍天數(shù)>=3天的用戶 SELECT user_id FROM ( SELECT user_id , active_date , lead_active_date FROM ( SELECT user_id , active_date , lead(active_date , 2 , 0) OVER(PARTITION BY user_id ORDER BY active_date) AS lead_active_date FROM user_active_info GROUP BY user_id , active_date ) a WHERE lead_active_date != '0' AND DATEDIFF(lead_active_date , active_date) = 2 ) b GROUP BY user_id
user_id |
---|
10001 |
10002 |
10003 |
10004 |
到此這篇關(guān)于SQL統(tǒng)計連續(xù)登陸3天用戶的實(shí)現(xiàn)示例的文章就介紹到這了,更多相關(guān)SQL統(tǒng)計連續(xù)登陸3天用戶內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SQL Server數(shù)據(jù)庫設(shè)置自動備份策略的完整步驟
這篇文章主要給大家介紹了關(guān)于SQL Server數(shù)據(jù)庫設(shè)置自動備份策略的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家學(xué)習(xí)或者使用sql server具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-09-09SQLServer XML數(shù)據(jù)的五種基本操作
SQLServer XML數(shù)據(jù)的五種基本操作語句2009-07-07sqlserver中向表中插入多行數(shù)據(jù)的insert語句
關(guān)于sql 2000中如何使用insert語句插入多行記錄,可是郁悶壞了我。2010-08-08SQLite3數(shù)據(jù)庫的介紹和使用教程(面向業(yè)務(wù)編程-數(shù)據(jù)庫)
這篇文章主要介紹了SQLite3數(shù)據(jù)庫的介紹和使用(面向業(yè)務(wù)編程-數(shù)據(jù)庫),本文從SQLite3的庫的獲取、工程管理、SQL語句介紹、C語言編程四個角度闡述了SQLite3數(shù)據(jù)庫的實(shí)際應(yīng)用,需要的朋友可以參考下2023-05-05SQL Server 2000/2005/2008刪除或壓縮數(shù)據(jù)庫日志的方法
最近win2008 r2的服務(wù)器比較卡,打開服務(wù)器顯示也特別慢,sqlserver業(yè)務(wù)費(fèi)正常執(zhí)行,服務(wù)器桌面操作也比較卡,經(jīng)過多方研究發(fā)現(xiàn)原來是sqlserver日志文件已經(jīng)達(dá)到了84G導(dǎo)致,這里就為大家分享一下解決方法,需要的朋友可以參考一下2019-09-09SQL SERVER函數(shù)之深入表值函數(shù)的處理分析
本篇文章是對表值函數(shù)進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-06-06sql中循環(huán)處理當(dāng)前行數(shù)據(jù)和上一行數(shù)據(jù)相加減
曾經(jīng),sql中循環(huán)處理當(dāng)前行數(shù)據(jù)和上一行數(shù)據(jù)浪費(fèi)了我不少時間,學(xué)會后才發(fā)現(xiàn)如此容易,其實(shí)學(xué)問就是如此,難者不會,會者不難。2014-08-08