• SQL教育行业案例:学员续费如何分析?(case when、窗口函数)


    【面试题】

    某线上学习平台设置学员线上学习阶梯,新学员购买50节课为一个学习阶段,学习完想要进入下个阶段必须再次购买,即续费(假设所有学员只能续费一次)并且每个学员可选择不同老师进行学习。

    1.现求出续费学员在续费前3个月内的总课量,3个月给学员上课老师数量,以及每个上课老师给学员的上课量。

    2.现求出每个续费学员在续费前的最后一节课的时间,以及对应的上课老师。

    【解题步骤】

    1.求出所有续费学员在续费前3个月内的总课量,3个月给学员上课老师数量,以及每个上课老师给学员的上课量。

    1)所有续费学员在续费前3个月内的总课量

    购买表中“订单类型”=2的为续费学员,上课信息在学员上课表中。要用到2个表,所以需要多表联结。

    学员上课表和购买表,通过学生id作为联结条件。

    使用哪种联结呢?

    因为续费、上课属于两表的共同数据,所以使用内联结。下面得到续费学员的上课信息。

    1. select *
    2. from 学员上课表 as a
    3. inner join 购买表 as b
    4. on a.学员id=b.学员id
    5. where b.订单类型=2;

     

     

    用case语句来判断,新增一列为“续费前3个月数”。如果(上课时间-续费时间)<=3,那么“续费前3个月数”列中对应的值标记为1。否则标记为null。

    1. select *,
    2. (case when
    3. timestampdiff(month,a.上课时间,b.续费时间)<=3
    4. then 1
    5. else null
    6. end) as 续费前三个月数
    7. from 学员上课表 as a
    8. inner join 购买表 as b
    9. on a.学员id=b.学员id
    10. where b.订单类型=2;

     

    对续费前3个月的记录进行计数(count)得出所有续费学员的总课量,对老师id 去重计数得出上课老师数量。

    条件计数用case when 

    1. select count(distinct a.老师id) as 上课老师数量,
    2. count(case when
    3. timestampdiff(month,a.上课时间,b.续费时间)<=3
    4. then 1
    5. else null end) as 续费前三个月数
    6. from 学员上课表 as a
    7. inner join 购买表 as b
    8. on a.学员id=b.学员id
    9. where b.订单类型=2;

     

    2)每个上课老师给学员的上课量。

    当有“每个”出现的时候,要想到《猴子 从零学会SQL》中讲过的用“分组汇总来”来实现。

    按老师id分组(group by ),汇总续费前三个月课程量(计数函count)。

    1. select a.老师id,
    2. count(case when
    3. timestampdiff(month,a.上课时间,b.续费时间)<=3
    4. then 1
    5. else null end) as 续费前三个月数
    6. from 学员上课表 as a
    7. inner join 购买表 as b
    8. on a.学员id=b.学员id
    9. where b.订单类型=2
    10. group by a.老师id;

     

     2.求出每个续费学员在续费前的最后一节课的时间,以及对应的上课老师。

    1)跟前面题目一样,找出购买表中“订单类型”=2的为续费学员。两表联结获得续费学员的上课信息。

    1. select *
    2. from 学员上课表 as a
    3. inner join 购买表 as b
    4. on a.学员id=b.学员id
    5. where b.订单类型=2;

     筛选早于续费日期的学习记录

    1. select *
    2. from 学员上课表 as a
    3. inner join 购买表 as b
    4. on a.学员id=b.学员id
    5. where b.订单类型=2
    6. and a.上课时间 < b.续费时间;

     

    2)题目要求查询“每个用户”,当每个出现的时候,就要想到分组汇总(group by或者窗口函数的partiotion  by)。

    3)续费前最后一节课的时间

    大白话翻译就是,上课时间最晚的课程信息。按照上课时间对每个学员id 的上课记录进行排名,然后取出最后一条课程数据就是。

    又涉及到分组,又涉及到排名的问题,要想到用《猴子 从零学会SQL》里讲过的窗口函数来实现。

    所以使用分组(窗口函数partiotion by学员id),并按最后交易时间降序排列(order by上课时间 desc),套入窗口函数的语法,得出下面的sql语句:

    1. select a.*,b.续费时间,
    2. row_number() over (
    3. partition by a.学员id
    4. order by a.上课时间 DESC ) as 上课时间排序
    5. from 学员上课表 as a
    6. inner join 购买表 as b
    7. on a.学员id=b.学员id
    8. where b.订单类型=2
    9. and a.上课时间 < b.续费时间;

     

     3)可以看到通过上课时间降序排序后,最晚的学习的记录是排在第一条,用where 筛选出每个学员的第1条记录,得出每个学员续费前的学习记录。

    1. select * from
    2. (select a.*,b.续费时间,
    3. row_number() over (
    4. partition by a.学员id
    5. order by a.上课时间 DESC ) as 上课时间排序
    6. from 学员上课表 as a
    7. inner join 购买表 as b
    8. on a.学员id=b.学员id
    9. where b.订单类型=2
    10. and a.上课时间 < b.续费时间) as c
    11. where 上课时间排序=1;

    【本题考点】

    1.条件判断,需要灵活使用case。

    2.多表联结的使用,学会判断使用哪种联结。

    3.熟悉时间差函数的用法,方便计算多少时间间隔内的数据。

    4.遇到对每个进行排名问题,首先要想到使用窗口函数来实现。

    转载于公众号:猴子数据分析

     

  • 相关阅读:
    DirectX12 - Triangle Culling and Winding Order(三角形的剔除与绕序)
    opensl学习——base16编码解码、base64编码解码、ASCII码表、扩展ASCII码
    计算机毕业设计之java+ssm基于web的实验室课程管理系统
    支付宝开放平台第三方代小程序开发,消息服务推送通知总结
    吴恩达机器学习系列课程笔记——第十二章:支持向量机(Support Vector Machines)
    k8s上线Java项目文件导出异常总结
    搜维尔科技:特斯拉称工厂内有两台人形机器人开始自主工作
    Mybatics-连接配置
    推荐一本AI+医疗书:《机器学习和深度学习基础以及医学应用》,附21篇精选综述
    SpringBoot学习笔记(2)——B站动力节点
  • 原文地址:https://blog.csdn.net/qq_41404557/article/details/126144113