最近登錄日期(一)
描述
某網站每天有很多人登錄,請你統計一下該網站每個用戶最近登錄是哪一天,用的是什么設備.
第1行表示user_id為2的用戶在2020-10-12使用了客戶端id為1的設備登錄了該網站
。。。
第4行表示user_id為3的用戶在2020-10-13使用了客戶端id為2的設備登錄了該網站
還有一個用戶(user)表,簡況如下:
還有一個客戶端(client)表,簡況如下:
請你寫出一個sql語句查詢每個用戶最近一天登錄的日子,用戶的名字,以及用戶用的設備的名字,並且查詢結果按照user的name升序排序,上面的例子查詢結果如下:
查詢結果表明:
fh最近的登錄日期在2020-10-13,而且是使用ios登錄的
wangchao最近的登錄日期也是2020-10-13,而且是使用ios登錄的
有一個登錄(login)記錄表,簡況如下:

第1行表示user_id為2的用戶在2020-10-12使用了客戶端id為1的設備登錄了該網站
。。。
第4行表示user_id為3的用戶在2020-10-13使用了客戶端id為2的設備登錄了該網站
還有一個用戶(user)表,簡況如下:

還有一個客戶端(client)表,簡況如下:

請你寫出一個sql語句查詢每個用戶最近一天登錄的日子,用戶的名字,以及用戶用的設備的名字,並且查詢結果按照user的name升序排序,上面的例子查詢結果如下:

fh最近的登錄日期在2020-10-13,而且是使用ios登錄的
wangchao最近的登錄日期也是2020-10-13,而且是使用ios登錄的
SQL如下
select u_n,c_n ,date from ( select a.user_id,a.date,b.name as u_n,c.name as c_n,row_number() over(partition by user_id order by date desc)as rn from login a left join user b on a.user_id=b.id left join client c on a.client_id=c.id )a where rn=1 order by u_n
最近登錄日期(二)
描述
某網站每天有很多人登錄,請你統計一下該網站新登錄用戶的次日成功的留存率,
有一個登錄(login)記錄表,簡況如下:
第1行表示user_id為2的用戶在2020-10-12使用了客戶端id為1的設備第一次新登錄了該網站
。。。
請你寫出一個sql語句查詢新登錄用戶次日成功的留存率,即第1天登陸之后,第2天再次登陸的概率,保存小數點后面3位(3位之后的四舍五入),上面的例子查詢結果如下:
有一個登錄(login)記錄表,簡況如下:

第1行表示user_id為2的用戶在2020-10-12使用了客戶端id為1的設備第一次新登錄了該網站
。。。
第4行表示user_id為3的用戶在2020-10-12使用了客戶端id為2的設備登錄了該網站
。。。
最后1行表示user_id為1的用戶在2020-10-14使用了客戶端id為2的設備登錄了該網站
請你寫出一個sql語句查詢新登錄用戶次日成功的留存率,即第1天登陸之后,第2天再次登陸的概率,保存小數點后面3位(3位之后的四舍五入),上面的例子查詢結果如下:

查詢結果表明:
user_id為1的用戶在2020-10-12第一次新登錄了,在2020-10-13又登錄了,算是成功的留存
user_id為2的用戶在2020-10-12第一次新登錄了,在2020-10-13又登錄了,算是成功的留存
user_id為3的用戶在2020-10-12第一次新登錄了,在2020-10-13沒登錄了,算是失敗的留存
user_id為4的用戶在2020-10-13第一次新登錄了,在2020-10-14沒登錄了,算是失敗的留存
固次日成功的留存率為 2/4=0.5
(sqlite里查找某一天的后一天的用法是:date(yyyy-mm-dd, '+1 day'),四舍五入的函數為round,sqlite 1/2得到的不是0.5,得到的是0,只有1*1.0/2才會得到0.5
mysql里查找某一天的后一天的用法是:DATE_ADD(yyyy-mm-dd,INTERVAL 1 DAY),四舍五入的函數為round)
SQL如下
select round(count(distinct user_id)*1.0/(select count(distinct user_id) from login) ,3) from login where (user_id,date) in (select user_id,DATE_ADD(min(date),INTERVAL 1 DAY) from login group by user_id);
最近登錄日期(三)
描述
牛客每天有很多人登錄,請你統計一下牛客每個日期登錄新用戶個數,
有一個登錄(login)記錄表,簡況如下:
第1行表示user_id為2的用戶在2020-10-12使用了客戶端id為1的設備登錄了牛客網,因為是第1次登錄,所以是新用戶
。。。
第4行表示user_id為2的用戶在2020-10-13使用了客戶端id為2的設備登錄了牛客網,因為是第2次登錄,所以是老用戶
。。
最后1行表示user_id為4的用戶在2020-10-15使用了客戶端id為1的設備登錄了牛客網,因為是第2次登錄,所以是老用戶
請你寫出一個sql語句查詢每個日期登錄新用戶個數,並且查詢結果按照日期升序排序,上面的例子查詢結果如下:
查詢結果表明:
2020-10-12,有3個新用戶(user_id為2,3,1)登錄
2020-10-13,沒有新用戶登錄
2020-10-14,有1個新用戶(user_id為4)登錄
2020-10-15,沒有新用戶登錄
有一個登錄(login)記錄表,簡況如下:

第1行表示user_id為2的用戶在2020-10-12使用了客戶端id為1的設備登錄了牛客網,因為是第1次登錄,所以是新用戶
。。。
第4行表示user_id為2的用戶在2020-10-13使用了客戶端id為2的設備登錄了牛客網,因為是第2次登錄,所以是老用戶
。。
最后1行表示user_id為4的用戶在2020-10-15使用了客戶端id為1的設備登錄了牛客網,因為是第2次登錄,所以是老用戶
請你寫出一個sql語句查詢每個日期登錄新用戶個數,並且查詢結果按照日期升序排序,上面的例子查詢結果如下:

查詢結果表明:
2020-10-12,有3個新用戶(user_id為2,3,1)登錄
2020-10-13,沒有新用戶登錄
2020-10-14,有1個新用戶(user_id為4)登錄
2020-10-15,沒有新用戶登錄
SQL如下
解法一:暴力破解法,求出每個用戶的首次登陸日期,並統計每個日期的人數即可,但題目要求當天沒有人的話要給出0,所以這里需要join一下自己,取沒有用戶登陸的日期;
select a.date,case when b.cnt is null then 0 else b.cnt end as cnt from (select distinct date from login )a left join (select date,count(1) as cnt from ( select id,user_id,client_id,date, row_number() over(partition by user_id order by date) as rn from login a )a where rn=1 group by date ) b on a.date=b.date
解法二: 用 (user_id,date) in (user_id,min(date)) 得到每天登陸的新用戶,最后用sum case when來統計
select distinct date, sum(case when (user_id,date) in (select user_id,min(date) from login group by user_id ) then 1 else 0 end ) from login group by date order by date
最近登錄日期(四)
描述
某網站每天有很多人登錄,請你統計一下每個日期新用戶的次日留存率。
有一個登錄(login)記錄表,簡況如下:
第1行表示user_id為2的用戶在2020-10-12使用了客戶端id為1的設備登錄了該網站,因為是第1次登錄,所以是新用戶
。。。
第4行表示user_id為2的用戶在2020-10-13使用了客戶端id為2的設備登錄了該網站,因為是第2次登錄,所以是老用戶
。。
最后1行表示user_id為4的用戶在2020-10-15使用了客戶端id為1的設備登錄了該網站,因為是第2次登錄,所以是老用戶
請你寫出一個sql語句查詢每個日期新用戶的次日留存率,結果保留小數點后面3位數(3位之后的四舍五入),並且查詢結果按照日期升序排序,上面的例子查詢結果如下:
查詢結果表明:
2020-10-12登錄了3個(user_id為2,3,1)新用戶,2020-10-13,只有2個(id為2,1)登錄,故2020-10-12新用戶次日留存率為2/3=0.667;
2020-10-13沒有新用戶登錄,輸出0.000;
2020-10-14登錄了1個(user_id為4)新用戶,2020-10-15,user_id為4的用戶登錄,故2020-10-14新用戶次日留存率為1/1=1.000;
有一個登錄(login)記錄表,簡況如下:

第1行表示user_id為2的用戶在2020-10-12使用了客戶端id為1的設備登錄了該網站,因為是第1次登錄,所以是新用戶
。。。
第4行表示user_id為2的用戶在2020-10-13使用了客戶端id為2的設備登錄了該網站,因為是第2次登錄,所以是老用戶
。。
最后1行表示user_id為4的用戶在2020-10-15使用了客戶端id為1的設備登錄了該網站,因為是第2次登錄,所以是老用戶
請你寫出一個sql語句查詢每個日期新用戶的次日留存率,結果保留小數點后面3位數(3位之后的四舍五入),並且查詢結果按照日期升序排序,上面的例子查詢結果如下:

查詢結果表明:
2020-10-12登錄了3個(user_id為2,3,1)新用戶,2020-10-13,只有2個(id為2,1)登錄,故2020-10-12新用戶次日留存率為2/3=0.667;
2020-10-13沒有新用戶登錄,輸出0.000;
2020-10-14登錄了1個(user_id為4)新用戶,2020-10-15,user_id為4的用戶登錄,故2020-10-14新用戶次日留存率為1/1=1.000;
2020-10-15沒有新用戶登錄,輸出0.000;
(注意:sqlite里查找某一天的后一天的用法是:date(yyyy-mm-dd, '+1 day'),sqlite里1/2得到的不是0.5,得到的是0,只有1*1.0/2才會得到0.5)
SQL如下
select c.date, round(count(d.user_id)/count(*),3)as p from (select a.date,b.user_id from (select distinct l1.date from login l1)a left join (select l2.user_id,min(l2.date) as f_date from login l2 group by l2.user_id)b on a.date=b.f_date ) as c left join (select distinct l3.user_id from login l3,login l4 where l3.user_id=l4.user_id and DATE_ADD(l3.date,INTERVAL 1 DAY)=l4.date) as d on c.user_id = d.user_id group by c.date
最近登錄日期(五)
描述
牛客每天有很多人登錄,請你統計一下牛客每個用戶查詢刷題信息,包括: 用戶的名字,以及截止到某天,累計總共通過了多少題。 不存在沒有登錄卻刷題的情況,但是存在登錄了沒刷題的情況,不會存在刷題表里面,有提交代碼沒有通過的情況,但是會記錄在刷題表里,只不過通過數目是0。
有一個登錄(login)記錄表,簡況如下:
第1行表示user_id為2的用戶在2020-10-12使用了客戶端id為1的設備登錄了牛客網
。。。
第5行表示user_id為3的用戶在2020-10-13使用了客戶端id為2的設備登錄了牛客網
有一個刷題(passing_number)表,簡況如下:
第1行表示user_id為2的用戶在2020-10-12通過了4個題目。
。。。
第3行表示user_id為1的用戶在2020-10-13提交了代碼但是沒有通過任何題目。
第4行表示user_id為4的用戶在2020-10-13通過了2個題目
還有一個用戶(user)表,簡況如下:
查詢結果表明:
fh在2020-10-12為止,總共通過了4道題,輸出為4
wangchao在2020-10-12為止,總共通過了1道題,總計為1
tm在2020-10-12為止只登陸了沒有刷題,故沒有顯示出來
tm在2020-10-13為止刷了題,但是卻沒有通過任何題目,總計為0
wangchao在2020-10-13通過2道,但是加上前面2020-10-12通過1道,故在2020-10-13為止總共通過了3道題,總計為3
有一個登錄(login)記錄表,簡況如下:

第1行表示user_id為2的用戶在2020-10-12使用了客戶端id為1的設備登錄了牛客網
。。。
第5行表示user_id為3的用戶在2020-10-13使用了客戶端id為2的設備登錄了牛客網
有一個刷題(passing_number)表,簡況如下:

第1行表示user_id為2的用戶在2020-10-12通過了4個題目。
。。。
第3行表示user_id為1的用戶在2020-10-13提交了代碼但是沒有通過任何題目。
第4行表示user_id為4的用戶在2020-10-13通過了2個題目
還有一個用戶(user)表,簡況如下:

請你寫出一個sql語句查詢刷題信息,包括: 用戶的名字,以及截止到某天,累計總共通過了多少題,並且查詢結果先按照日期升序排序,再按照姓名升序排序,有登錄卻沒有刷題的哪一天的數據不需要輸出,上面的例子查詢結果如下:

查詢結果表明:
fh在2020-10-12為止,總共通過了4道題,輸出為4
wangchao在2020-10-12為止,總共通過了1道題,總計為1
tm在2020-10-12為止只登陸了沒有刷題,故沒有顯示出來
tm在2020-10-13為止刷了題,但是卻沒有通過任何題目,總計為0
wangchao在2020-10-13通過2道,但是加上前面2020-10-12通過1道,故在2020-10-13為止總共通過了3道題,總計為3
解題思路
1.先找出每個用戶都在那一天登陸了:
select distinct user_id,date from login
2.然后去與passing_number表關聯小於或等於當前日期的數據,當然也別忘了關聯user表去取一下name:
select c.name,a.user_id ,a.date,b.number from (select distinct user_id,date from login) a, passing_number b , user c where a.user_id=b.user_id and a.user_id =c.id and b.date<=a.date
3.最后求每個user每天的刷題數量,用sum()+group by 即可:
SQL如下
select name,date,sum(number) from ( select c.name,a.user_id ,a.date,b.number from (select distinct user_id,date from login) a, passing_number b , user c where a.user_id=b.user_id and a.user_id =c.id and b.date<=a.date ) b group by name ,date order by date, name
本文SQL題目來源於牛客網