题目表述
表: Signups
User_id是该表的主键。
每一行都包含ID为user_id的用户的注册时间信息。
表: Confirmations
(user_id, time_stamp)是该表的主键。
user_id是一个引用到注册表的外键。
action是类型为(‘confirmed’, ‘timeout’)的ENUM
该表的每一行都表示ID为user_id的用户在time_stamp请求了一条确认消息,该确认消息要么被确认(‘confirmed’),要么被过期(‘timeout’)。
用户的 确认率 是 ‘confirmed’ 消息的数量除以请求的确认消息的总数。没有请求任何确认消息的用户的确认率为 0 。确认率四舍五入到 小数点后两位 。
编写一个SQL查询来查找每个用户的 确认率 。
以 任意顺序 返回结果表。
解释:
用户 6 没有请求任何确认消息。确认率为 0。
用户 3 进行了 2 次请求,都超时了。确认率为 0。
用户 7 提出了 3 个请求,所有请求都得到了确认。确认率为 1。
用户 2 做了 2 个请求,其中一个被确认,另一个超时。确认率为 1 / 2 = 0.5。
答题过程:
第一眼看到这种格式的数据,我想到了行列转换然后计数的方式。先把action
列 按照超时的 和 确认的 分开 再按照 user_id
进行分组然后计算 ,最后注意一下四舍五入就行了。
select user_id ,
//这个地方是避免 除数为0的情况 先判断除数如果为零 则确认率直接为0就行
case when timeout+confirmed = 0
then 0
else round(confirmed/(timeout+confirmed),2) end confirmation_rate
from(
select s1.user_id,
//行列转换 符合条件的 赋值给1 不符合的 给0 最后用sum求和 计数
sum( case when action = 'timeout' then 1 else 0 end) timeout,
sum(case when action = 'confirmed' then 1 else 0 end) confirmed
from Signups s1
left join Confirmations C1
on s1.user_id = c1.user_id
group by s1.user_id
)