SQL實用題型 使用者最長連續登陸天數

2021-09-27 10:36:56 字數 3406 閱讀 5067

已知:乙個簡單的使用者登陸表:

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.還原場景 建...