暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MYSQL之进阶实战笔试题(一)

奈奈八尾 2021-04-12
231

现有一表user_login_table代表表名

user_name代表用户ID

date代表用户登录时间

其结构数据如下:


例题1:求连续7天登录过的用户ID


思路一:首先对用户登录的日期去重-通过row_number窗口函数对每个用户登录时间升序排列得到新列rn-通过date1列减去rn列得到一个新列date2-通过判断date_2的计数>=7即可得到连续登录7天的用户。

具体代码如下:

select user_name,

       date2

from (select *,

               date1-rn date2

         from(select * ,

                      row_number () over (partition  by user_name order by date1 ) as rn

                  from (select distinct date(date) as date1,

                                  user_name 

                             from user_login_table)b)c)d

group by  user_name,date2 

having count(*)>=7;


补充知识点:

  • 排名窗口函数

  • 离散的组内排序(113)-rank()   over (partition by ... order by ... )

  • 连续的组内排序(112)-dense_rank()  over (partition by ... order by ... )

  • 当前行在组内的序号(123)-row_number()  over (partition by ... order by ... )

  • 子查询

  • where子查询-指把内层查询结果作为外层查询的比较条件

  • from子查询-把内层sql的查询结果,当成临时表供外层sql再次查询,临时表

需要声明表名

  • exist子查询-指把外层sql的结果,拿到内层sql比较,为真则输出结果



思路二:通过lead函数将date列日期向后偏移7次,通过偏移7次后的日期与date列日期向后7天的日期比较,如果两者相等,则说明用户连续登录了7天。

具体代码如下:

select user_name

from (select user_name,

              CAST(date as date) as date_1,

              LEAD(CAST(date AS date),7) over (partition by user_name order by date) as date_2

        from user_login_table) a

where  DATE_ADD(a.date_1,INTERVAL 6 day)=a.date_2;


补充知识点:

  • 将值转换为指定类型-CAST(字段名 as  转换类型)

转换类型可为以下类型:

  • CHAR[(N)] 字符型

  • DATE  日期型

  • DATETIME  日期和时间型

  • DECIMAL  float型

  • SIGNED  int

  • TIME  时间型

  • 向后偏移-LEAD(字段名,偏移量,默认null) over(partition by ...order by …)   向前偏移-LAG(字段名,偏移量,默认null) over(partition by ...order by …)

  • 向日期添加指定时间间隔-DATE_ADD(字段名,INTERVAL 时间间隔  单位)

 常用单位可为以下类型:

向日期减去指定时间间隔-DATE_SUB(字段名,INTERVAL 时间间隔  单位)

单位如上图所示。

  •   


文章转载自奈奈八尾,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论