已知:乙個簡單的使用者登陸表:
uiddat
u12019/9/1
u12019/9/2
u12019/9/3
u12019/9/8
u12019/9/9
u22019/9/2
u22019/9/3
想要得到:查詢結果如下
uidmax_dayu13
u12u22
首先想到的是用count+group by的用法,那麼group by後面用於分組的條件就是連續登陸的標記(分別為連續登陸2天,3天,6天,10 天等等)。
如何對於每乙個使用者構建連續登陸的標記? 這個時候,很容易就會想到平時演算法中的相鄰迴圈加1,但是在sql中一定要轉變這種思維方式,而是思考能不能給這些連續加1的日期打上乙個相同的標籤,這樣子就可以利用這個標籤當作group by分組的條件了。
以使用者u1為例,該使用者有兩次連續登陸的經歷,第一次是連續3天,第二次是連續2天,我們只要能對這兩次的連續登陸行為打上兩個標籤,則可以使用group by對於不同標籤組內的資料進行count的計算,從而得到使用者的連續登陸天數這一新變數。
以使用者u1連續登陸3天的3個資料為例,怎麼給著三個資料打上同樣的標籤呢?此時我們思考,這三個資料date1,date2,date3的關係是數值上依次加1,加入我們可以生成一列同樣依次加1的資料r1,r2,r3(如1,2,3),那麼date1-r1的差值就會等於date2-r2同時等於date3-r3,那麼我們就可以使用這個差值作為乙個連續登陸的標記,所以同樣對於使用者u1連續登陸2天的2個資料,我們也用該種方法進行連續登陸的標記。
這個時候我們需要思考乙個問題,如果兩次做差的數值a,b是相同的應該怎麼辦?這樣的話,就會把原來分開的兩次連續登陸(3天標籤a,2天標籤b)計算成一次的連續登陸(5天標籤a=標籤b)。此時我們應該想到,連續登陸的3天和2天的日期一定不是相鄰的,是跳躍的,否則就會記做一次登陸5天。那麼只要我們生成一串長長的自然數列(1,2,3,4,5,6…)剛好依次對應與使用者登陸的日期,然後我們使用這個自然數列和使用者登陸的日期做差,這樣就一定能得到兩組標籤了。這裡再解釋一遍因為如果是連續登陸的話,使用者的日期是連續的(d1,d2,d3),我們使用自然數列(1,2,3)與它做差,得到的數字是相同的數字d1-1=d2-2=d3-3=a,可以用作一次連續登陸行為的標籤,當使用者隔了幾天之後再次出現連續登陸行為(d4,d5)時,重新開始連續登陸日期數字已經跳到幾天之後(即d4與d3不再是加1的關係),但是與該日期(d4,d5)依次對應的自然數列(4,5)與之前的(1,2,3)還是相鄰的關係。這樣的話d4-4=d5-5=b 且不等於 d3-3=a這樣我們就給d4和d5建立了乙個新的標籤。所以我們連續登陸3天和2天的日期後面對應的標籤是兩個不同的數字a,b。
那麼如何實現生成一串自然數列的功能呢,當然是使用我們的row_number()函式啦,因為我們是對每乙個使用者進行如上的操作,所以over()中的條件應該是partition by uid, 同時題目沒有說日期變數是有序的,所以我們還應該加上order by dat這一條件。
故實現該連續登陸的標記部分的查詢語句應該是:
select uid, dat,
(day
(dat)
- row_number(
)over
(partition
by uid order
by dat)
)as day_label
from
table
故計算連續登陸天數day_count的語句是:
select uid,day_label,
count(*
)as day_count
from
(select uid, dat,
(day
(dat)
- row_number(
)over
(partition
by uid order
by dat)
)as day_label from
table
)group
by uid,day_label
故求最大連續登陸天數max(day_count)的語句是:
select uid,
max(day_count)
as max_day
from
(select uid,day_label,
count(*
)as day_count
from
(select uid, dat,
(day
(dat)
- row_number(
)over
(partition
by uid order
by dat)
)as day_label from
table
)group
by uid,day_label)
group
by uid
9.最後再解釋一下**,共三層巢狀子查詢,最內層使用開窗函式給每一批連續登陸的日期都打上每一批對應的day_label標籤,第二層子查詢是利用上一層的標籤作為group by分類計數的類別,這一層的查詢是得到了使用者每一次連續登陸對應的天數。第三層的子查詢就是使用max函式與group by函式取出每乙個使用者對應的最長登陸天數。
分析題意,搞清楚題目的邏輯順序,先求連續登陸天數,再取最大
思維方式要使用sql中的歸類思想,建立一組變數,使得它們能夠作為分類的標籤。
思考細節,日期是否需要排序,順序還是倒序
熟悉開窗函式的應用
SQL 求使用者最大連續登陸天數
因為用了別人的結果圖,沒有自己一步一步跑結果,有需要的小夥伴,自己對照一下哈 做題思路。1.row number 找到xx按某個順序a的排名。是否連續,一定是按某個順序,找到這個順序並進行排名r。2.找規律。進行排名後因為是順序,a也是這個順序。如果連續的話,a r就是乙個同乙個數字,不連續的話就是...
SQL查詢語句求出使用者的連續登陸天數
求解使用者登陸資訊表中,每個使用者連續登陸平台的天數,連續登陸基礎為彙總日期必須登陸,表中每天只有一條使用者登陸資料 計算中不涉及天內去重 表描述 user id 使用者的id sigin date 使用者的登陸日期。注 求解過程有多種方式,下述求解解法為筆者思路,其他解法可在評論區交流。思路 該問...
SQL經典面試題 連續3天登陸
sql經典面試題系列 前段時間六師妹去某團面試,回來後一直鬱鬱寡歡。好奇心下得知,原來是面試官要求小六用sql實現手寫 連續3天登入使用者 這個問題雖然說難不難,但說易也不簡單,而且,偏受大小廠喜歡。其實,不管是數倉 etl bi 資料分析 大資料等方向,都會經常被面試 筆試考察到。1.還原場景 建...