前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大数据面试SQL048-泳池问题(下)

大数据面试SQL048-泳池问题(下)

作者头像
数据仓库晨曦
发布2024-04-11 14:24:01
470
发布2024-04-11 14:24:01
举报
文章被收录于专栏:数据仓库技术数据仓库技术

一、题目

我们接着上两题继续讨论泳池问题,还是相同的数据。现有一份数据记录了用户进入和离开游泳池的时间,请计算出泳池内的平均人数

代码语言:javascript
复制
--样例数据
+----------+-----------+----------------------+
| user_id  | log_type  |       log_time       |
+----------+-----------+----------------------+
| 1        | enter     | 2024-04-07 08:01:00  |
| 2        | enter     | 2024-04-07 08:20:00  |
| 1        | leave     | 2024-04-07 09:30:00  |
| 3        | enter     | 2024-04-07 10:01:00  |
| 4        | enter     | 2024-04-07 10:25:00  |
| 2        | leave     | 2024-04-07 11:22:00  |
| 4        | leave     | 2024-04-07 12:20:00  |
| 5        | enter     | 2024-04-07 12:30:00  |
| 6        | enter     | 2024-04-07 13:05:00  |
| 3        | leave     | 2024-04-07 14:20:00  |
| 5        | leave     | 2024-04-07 14:30:00  |
| 7        | enter     | 2024-04-07 14:45:00  |
| 8        | enter     | 2024-04-07 15:18:00  |
| 7        | leave     | 2024-04-07 15:32:00  |
| 6        | leave     | 2024-04-07 15:45:00  |
| 9        | enter     | 2024-04-07 16:01:00  |
| 10       | enter     | 2024-04-07 16:10:00  |
| 9        | leave     | 2024-04-07 16:25:00  |
| 8        | leave     | 2024-04-07 16:35:00  |
| 10       | leave     | 2024-04-07 16:55:00  |
+----------+-----------+----------------------+

二、分析

这个题目是在前两个题目的进一步升级,这里并没有再进一步考察什么函数,而是考察业务知识。想要计算平均值,我们可以一个全天泳池内所有人累计时长,然后除以泳池的开放时长,就是泳池内的平均人数;

维度

评分

题目难度

⭐️⭐️⭐️⭐️

题目清晰度

⭐️⭐️⭐️⭐️⭐

业务常见度

⭐️⭐️⭐️⭐️

三、SQL

1)使用之前的结果,我们计算出泳池中的人数和持续时间,然后对人数*时间结果求和,即为一天内所有人的累计时长。使用上一个题目的中间结果,先计算出每行记录的人数pool_user_cnt和持续时间keep_sec。

代码语言:javascript
复制
select 
 user_id,
 log_type,
 log_time,
 enter_cnt,
 pool_user_cnt,
 next_log_time,
 unix_timestamp(next_log_time) - unix_timestamp(log_time) as keep_sec
from
(select
 user_id,
 log_type,
 log_time,
 enter_cnt,
 sum(enter_cnt)over(order by log_time asc) as pool_user_cnt,
 lead(log_time,1,'2024-04-07 17:00:00')over(order by log_time asc) as next_log_time
from 
(
    select 
  user_id,
  log_type,
  log_time,
  if(log_type ='enter',1,-1) as enter_cnt 
 from t_user_pool_log
) t
) tt

查询结果

2)计算出pool_user_cnt*keep_sec 的结果

代码语言:javascript
复制
select 
user_id,
log_type,
log_time,
pool_user_cnt,
next_log_time,
keep_sec,
pool_user_cnt*keep_sec as user_keep_sec
from
(select 
 user_id,
 log_type,
 log_time,
 enter_cnt,
 pool_user_cnt,
 next_log_time,
 unix_timestamp(next_log_time) - unix_timestamp(log_time) as keep_sec
from
(select
 user_id,
 log_type,
 log_time,
 enter_cnt,
 sum(enter_cnt)over(order by log_time asc) as pool_user_cnt,
 lead(log_time,1,'2024-04-07 17:00:00')over(order by log_time asc) as next_log_time
from 
(
    select 
  user_id,
  log_type,
  log_time,
  if(log_type ='enter',1,-1) as enter_cnt 
 from t_user_pool_log
) t
) tt
)ttt

查询结果

3)我们假设泳池开放时间为8:00~17:00 计算出总的时间长度total_sec.对user_keep_sec 求和之后除以total_sec 得到平均人数。

代码语言:javascript
复制
select
sum(user_keep_sec)/(unix_timestamp('2024-04-07 17:00:00')-unix_timestamp('2024-04-07 08:00:00')) as avg_num
from 
(select 
user_id,
log_type,
log_time,
pool_user_cnt,
next_log_time,
keep_sec,
pool_user_cnt*keep_sec as user_keep_sec
from
(select 
 user_id,
 log_type,
 log_time,
 enter_cnt,
 pool_user_cnt,
 next_log_time,
 unix_timestamp(next_log_time) - unix_timestamp(log_time) as keep_sec
from
(select
 user_id,
 log_type,
 log_time,
 enter_cnt,
 sum(enter_cnt)over(order by log_time asc) as pool_user_cnt,
 lead(log_time,1,'2024-04-07 17:00:00')over(order by log_time asc) as next_log_time
from 
(
    select 
  user_id,
  log_type,
  log_time,
  if(log_type ='enter',1,-1) as enter_cnt 
 from t_user_pool_log
) t
) tt
)ttt
 )tttt

查询结果

4)简化SQL

代码语言:javascript
复制
select
sum(pool_user_cnt*keep_sec)/(unix_timestamp('2024-04-07 17:00:00')-unix_timestamp('2024-04-07 08:00:00')) as avg_num
from
(select
 user_id,
 log_type,
 log_time,
 enter_cnt,
 sum(enter_cnt)over(order by log_time asc) as pool_user_cnt,
 unix_timestamp(lead(log_time,1,'2024-04-07 17:00:00')over(order by log_time asc))-unix_timestamp(log_time) as keep_sec
from 
(
    select 
  user_id,
  log_type,
  log_time,
  if(log_type ='enter',1,-1) as enter_cnt 
 from t_user_pool_log
) t
) tt

查询结果

四、建表语句和数据插入

代码语言:javascript
复制
--建表语句
CREATE TABLE t_user_pool_log (
  user_id INT,
  log_type STRING,
  log_time STRING
)
COMMENT '泳池进出日志表'
ROW FORMAT DELIMITED
  FIELDS TERMINATED BY ',' 
  LINES TERMINATED BY '\n'
STORED AS TEXTFILE;
-- 样例数据插入
insert into t_user_pool_log values
(1,'enter','2024-04-07 08:01:00'),
(2,'enter','2024-04-07 08:20:00'),
(1,'leave','2024-04-07 09:30:00'),
(3,'enter','2024-04-07 10:01:00'),
(4,'enter','2024-04-07 10:25:00'),
(2,'leave','2024-04-07 11:22:00'),
(4,'leave','2024-04-07 12:20:00'),
(5,'enter','2024-04-07 12:30:00'),
(6,'enter','2024-04-07 13:05:00'),
(3,'leave','2024-04-07 14:20:00'),
(5,'leave','2024-04-07 14:30:00'),
(7,'enter','2024-04-07 14:45:00'),
(8,'enter','2024-04-07 15:18:00'),
(7,'leave','2024-04-07 15:32:00'),
(6,'leave','2024-04-07 15:45:00'),
(9,'enter','2024-04-07 16:01:00'),
(10,'enter','2024-04-07 16:10:00'),
(9,'leave','2024-04-07 16:25:00'),
(8,'leave','2024-04-07 16:35:00'),
(10,'leave','2024-04-07 16:55:00');

本文同步在微信公众号”数据仓库技术“和个人博客”数据仓库技术“发表。原文:www.dwsql.com

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2024-04-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据仓库技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、题目
  • 二、分析
  • 三、SQL
相关产品与服务
大数据
全栈大数据产品,面向海量数据场景,帮助您 “智理无数,心中有数”!
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档