免费教程《图解 SQL 面试题》
  • 图解 SQL 面试题
  • 第 1 章:简单查询
  • 图解面试题:如何查找重复数据?
  • 第 2 章:复杂查询
    • 图解面试题:如何查找第 N 高的数据?
  • 第 3 章 多表查询?
    • 图解面试题:多表如何查询?
    • 图解面试题:如何查找不在表里的数据?
    • 图解面试题:你有多久没涨过工资了?
    • 图解面试题:如何比较日期数据?
    • 图解面试题:如何交换数据?
    • 滴滴 2020 年面试题:如何找出最小的 N 个数?
    • 图解面试题:行列互换问题,怎么办?
    • 图解面试题:找出连续出现 N 次的内容?
    • 链家面试题:如何分析留存率?
  • 第 4 章
    • 拼多多面试题:如何查找前 20% 的数据?
    • 图解面试题:如何查找工资前三高的员工
    • 图解面试题:如何分组比较?
    • 图解面试题:双 11 用户如何分析?
    • 图解面试题:如何分析游戏?
  • 第 5 章:项目实战
    • 图解面试题:滴滴 2020 求职真题
    • 滴滴面试题:打车业务问题如何分析?
    • 电商面试题:如何分析复杂业务?
    • 图解面试题:如何分析用户满意度?
    • 图解面试题:如何分析红包领取情况?
    • 图解面试题:如何分析中位数?
    • 小红书面试题:如何分析用户行为?
    • 教育行业案例:学员续费如何分析?
    • 字节跳动面试题:你的平均薪水是多少?
Powered by GitBook
On this page

Was this helpful?

  1. 第 5 章:项目实战

图解面试题:如何分析用户满意度?

Previous电商面试题:如何分析复杂业务?Next图解面试题:如何分析红包领取情况?

Last updated 4 years ago

Was this helpful?

【题目】

“满意度表”记录了教师和学生对课程的满意程度。“是否满意”列里是老师和学生对课程的评价,其中 “是” 表示教师和学生都满意。

“用户表” 记录了学校教师和学生的信息。每个用户有唯一键 “编号”,“是否在系统” 表示这个用户是否还在这所学校里,“角色” 表示这个人是学生还是教师。

两个表的关系:满意度表的 “学生编号” 、 “教师编号” 和用户表的 “编号” 联结。

现在需要分析出学校里人员对课程的满意度。满意度的计算方式如下:

(教师和学生对课程都满意且已存在当前教务系统中的用户) / (在学校里的人数)

【解题思路】

1. 多表联结

那么,使用哪种联结呢?

统计值为满意度,所以使用 “满意度表” 为主表,进行左联结。

select * 
from 满意度表
left join 用户表;

如何联结呢?

两个表的关系:满意度表的 “学生编号” 、 “教师编号” 和用户表的 “编号” 联结。所以联结条件是:

满意度表. 教师编号 = 用户表. 编号 or 满意度表. 学生编号 = 用户表. 编号

基于上面的分析,多表联结查询 sql 语句如下:

select * 
from 满意度表
left join 用户表
on (满意度表.教师编号 = 用户表.编号 or 
    满意度表.学生编号 = 用户表.编号);

2. 查询条件

满意度等于:

(教师和学生对课程都满意且已存在当前教务系统中的用户) / (在学校里的人数)

由这个公式可以知道,分子和分母计算的前提都是存在学校里的用户。所以,查询条件是:用户表中存在学校里的用户。

where 用户表.是否在系统 = '是'

把条件子句加入前面的多表查询 sql 里,就是下面的 sql:

select * 
from 满意度表
left join 用户表
on (满意度表.教师编号 = 用户表.编号 or 满意度表.学生编号 = 用户表.编号)
where 用户表.是否在系统 = '是';

3. 统计

满意度等于:

(教师和学生对课程都满意且已存在当前教务系统中的用户) / (在学校里的人数)

我把这个公示简化为:满意度 = a/b

其实 a = 教师和学生对课程都满意且已存在当前教务系统中的用户

b = 在学校里的人数

我们只需要把 a 和 b 的值计算出来就可以啦。

1)计算 a

统计好 “是否满意” 列里有多少个值为“是”。

我们可以把 “是” 转化成 1,然后累计求和,对应的 sql 就是:

sum(if(是否满意='是',1,0)

2)计算 b

b = 在学校里的人数,直接用计数函数(count)就可以:count(是否满意)

3)计算出满意度

满意度 = a/b,也就是

sum(if(是否满意='是',1,0))/count(是否满意) as 满意度

把这个计算公示加入前面 sql 语句的查询结果里就是(下面的 select 子句):

select sum(if(满意度表.是否满意='是',1,0))/count(满意度表.是否满意) as 满意度
from 满意度表
left join 用户表
on (满意度表.教师编号 = 用户表.编号 or 满意度表.学生编号 = 用户表.编号)
where 用户表.是否在系统 = '是';

最后查询结果是满意度 = 0.75。

【本题考点】

● 考察多表查询的应用

● 如何将业务需求转换为 sql 语句的能力

● 聚合函数的运用

【举一反三】

下表是一家出行公司(比如滴滴、Uber)的数据库表。乘客通过该公司的 app 叫车,司机通过 app 接收订单。

Users 表里存放的是用户信息。每个用户有唯一值(Users_Id) 。Banned 表示用户是否因为违规被禁止使用 app。Role 记录了用户的角色,里面的值 driver 是司机,client 是乘客,partner 是合伙人。

Trips 表记录了各个出租车的行程信息。每段行程有唯一键(Id) 。Status 行程类型 ‘completed’表行程正常结束, ‘cancelled_by_driver’ 表示行程因为司机原因取消,‘cancelled_by_client’表示行程因为乘客原因取消。

两个表的联结关系:Trips 表(Client_Id 、 Driver_Id) 和 Users 表中 Users_Id 的联结。

写一段 SQL 语句查出非禁止用户的取消率。

取消率的计算方式如下:(被司机或乘客取消的非禁止用户生成的订单数量) / (非禁止用户生成的订单总数)

参考答案:

1.两表联结,找出非禁止的用户

select *
from trips
left join users_id
on (trips.Client_Id = users_id.Users_Id or trips.Driver_Id = users_id.Users_Id)
where users_id.banned = 'no';

2.按日期分组

因为要计算的是 “每天” 的取消率,所以要按日期分组,统计每一天的。

group by trips.request_at

3.计算取消率

被司机或乘客取消的非禁止用户生成的订单数量 =

sum(if(status = 'completed',0,1))

非禁止用户生成的订单总数 = count(status)

最终 sql 如下:

select sum(if(trips.status = 'completed',0,1)) / count(trips.status)
from trips
left join users_id
on (trips.Client_Id = users_id.Users_Id or trips.Driver_Id = users_id.Users_Id)
where users_id.banned = 'no'
group by trips.request_at;

统计满意度的前提是需要用户在学校里,需要用到 “用户表” 里的 “是否在系统” 来判断。满意度需要用到“满意度表”。所以涉及到两个表里的数据,就要用到《》里讲过的多表联结。

推荐:

猴子 从零学会 sql
如何从零学会 sql?