sql面试题——手写sql案例(二))

目录

 

1. 求:每个店铺的UV(访客数)每个店铺的访问次数top3

2. 给出 2017年每个月的订单数、用户数、总成交金额

3.求得所有用户和活跃用户的总数及平均年龄


1. 求:每个店铺的UV(访客数)每个店铺的访问次数top3

有50W个京东店铺,每个顾客访客访问任何一个店铺的任何一个商品时都会产生一条访问日志,访问日志存储的表名为Visit,访客的用户id为user_id,被访问的店铺名称为shop,请统计:

1)每个店铺的UV(访客数)

2)每个店铺访问次数top3的访客信息。输出店铺名称、访客id、访问次数

数据:

u1	a
u2	b
u1	b
u1	a
u3	c
u4	b
u1	a
u2	c
u5	b
u4	b
u6	c
u2	c
u1	b
u2	a
u2	a
u3	a
u5	a
u5	a
u5	a

 先建表

create table visit(
user_id string,
shop string
) 
row format delimited fields terminated by '\t';

1.1每个店铺的UV(访客数)

select
    shop,
    count(distinct user_id)
from visit
group by shop;

1.2 每个店铺访问次数top3的访客信息。输出店铺名称、访客id、访问次数

1.2.1 查询每个店铺被每个用户访问次数

select
    shop,
    user_id,
    count(*) ct
from visit
group by shop,user_id;t1

1.2.2 计算每个店铺被用户访问次数排名

select
     shop,
     user_id,
     ct, 
     rank() over(partition by shop order by ct) rk
from t1;t2

1.3 取每个店铺的前三

select
    shop,
    user_id,
    ct
from t2
where rk<=3

1.4 最终sql

select 
   shop,
   user_id,
   ct
from
 (select 
   shop,
   user_id,
   ct,
   rank() over(partition by shop order by ct) rk
from 
 (select 
   shop,
   user_id,
   count(*) ct
from visit
group by 
   shop,
   user_id)t1
)t2
where rk<=3;

2. 给出 2017年每个月的订单数、用户数、总成交金额

已知一个表STG.ORDER,有如下字段:Date,Order_id,User_id,amount。请给出sql进行统计:数据样例:2017-01-01,10029028,1000003251,33.57。

1)给出 2017年每个月的订单数、用户数、总成交金额。

2)给出2017年11月的新客数(指在11月才有第一笔订单)

先建表

create table order_tab(
   dt string,
   order_id string,
   user_id string,
   amount decimal(10,2)
) 
row format delimited fields terminated by '\t';

2.1 给出2017年每个月的订单数、用户数、总成交金额

select
    date_format(dt,'yyyy-MM'),
    count(order_id),
    count(distinct user_id),
    sum(amount)
from order_tab
where
    date_format(dt,'yyyy')='2017'
group by
    data_format(dt,'yyyy-MM');

2.2 给出2017年11月的新客数(指在11月才有第一笔订单)

select
    count(user_id)
from
    order_tab
group by
    user_id
having
    date_format(min(dt),'yyyy-MM')='2017-11';

3.求得所有用户和活跃用户的总数及平均年龄

有日志如下,请写出代码求得所有用户和活跃用户的总数及平均年龄。(活跃用户指连续两天都有访问记录的用户)

数据

日期(dt)

用户(user_id)

年龄(age)

2019-02-11

test_1

23

2019-02-11

test_2

19

2019-02-11

test_3

39

2019-02-11

test_1

23

2019-02-11

test_3

39

2019-02-11

test_1

23

2019-02-12

test_2

19

2019-02-13

test_1

23

2019-02-15

test_2

19

2019-02-16

test_2

19

先建表

create table user_age(
      dt string,
      user_id string,
      age int
)
row format delimited fields terminated by ',';

3.1 按照日期以及用户分组,按照日期排序并给出排名

select
    dt,
    user_id,
    min(age) age,
    rank() over(partition by user_id order by dt) rk
from user_age
group by
    dt,user_id;t1

3.2 计算出日期及排名的差值

select
    user_id,
    age,
    date_sub(dt,rk) flag
from t1;t2

3.3 过滤出差值大于等于2的,即为连续两天活跃的用户

select
    user_id,
    min(age) age
from t2
group by
    user_id,
    flag
having
    coount(*)>=2;t3

3.4 对数据进行去重处理(一个用户可以在多个不同的时间点连续登录)

select
    user_id
    min(age) age
from t3
group by
    user_id;t4

3.5 计算活跃用户(两天连续有访问)的人数以及平均年龄

select
    count(*) ct,
    cast(sum(age)/count(*) as decimal (10,2))
from t4;

3.6 对全局数据集进行按照用户去重

select
    user_id,
    min(age) age
from user_age
group by user_id;t5

3.7 计算所有用户的数量以及平均年龄

select
    count(*) user_count,
    cast((sum(age)/count(*)) as decimal(10,1))
from t5;

3.8 将第4步以及第6步两个数据集进行union all操作

select
    0 user_total_count,
    0 user_total_avg_age,
    count(*) twice_count,
    cast(sum (age)/count(*) as decimal(10,2))twice_count_avg_age
from(
  select
    user_id,
    min(age) age
from(
  select
    user_id,
    age,
    date_sub(dt,rk) flag
from(
  select
    dt,
    user_id,
    min(age) age,
    rank() over(partition by user_id order by dt) rk
  from
    user_age
  group by
    dt,user_id
)t1
)t2
group by
    user_id,flag
having
    count(*)>=2
)t3
group by user_id
)t4

union all

select
    count(*) user_total_count,
    cast((sum(age)/count(*)) as decimal(10,1)),
    0 twice_count,
    0 twice_count_avg_age
from(
  select
     user_id,
     min(age) age 
  from 
      user_age 
  group by 
      user_id
 )t5;t6

猜你喜欢

转载自blog.csdn.net/Poolweet_/article/details/109614982
今日推荐