sql面试题_求秒杀时商品的hold时长

sql面试题20200607

表结构

以下是数据库中 4 个表的表结构:

表一:订单表(表名:table_order),主键是order_id+goods_id,用于记录每个订单的商品明细。同一个订单可能有多个商品,每条信息记录每个订单里不同商品的件单价和销售件数等,销售额=件单价price*销售件amount

order_id user_id goods_id add_time price amount department_id
1236 111 20340 2014/3/22 1:19 398.00 1 1
1236 111 12432 2014/3/22 1:19 18.00 2 2
1648 333 56235 2014/4/11 21:00 399.00 3 3
1648 333 42521 2014/4/11 21:00 290.00 1 4
1648 333 24466 2014/4/11 21:00 279.00 2 1
2060 222 25948 2014/3/30 13:21 190.00 2 2
2472 222 20942 2014/4/22 9:59 380.00 1 3
2472 222 98303 2014/4/22 9:59 299.00 1 4
2472 222 39555 2014/4/22 9:59 848.00 2 4
2884 444 20249 2014/5/7 17:53 599.00 1 2
2884 444 39523 2014/5/7 17:53 699.00 1 2

备注:order_id:订单号,add_time:下单时间,user_id:客户号,goods_id:商品编号,price:件单价,amount:销售件数,department_id:品类编号

表二:品类表(表名:table_department),主键是department_id。

department_id department_name
1 女装
2 女鞋
3 男装
4 男鞋

表三:客户表(表名:table_user),主键是user_id。

user_id user_name
111 张敏
222 黎佳
333 杨峰
444 催楠

备注:user_id:客户号,user_name:客户姓名

表:购物车表(表名:table_cart),主键是user_id+goods_id+add_time,用于记录客户不同时点放入购物车的商品情况(商品ID、商品数量、商品删除时间、商品购买时间)

user_id goods_id amount add_time delete_time buy_time
111 56235 2 2014/10/22 10:01 2014/10/22 10:20
111 24466 1 2014/10/22 10:21 2014/10/22 10:29
111 25948 3 2014/10/22 10:24
111 39555 1 2014/10/22 21:20 2014/10/22 21:26
111 98303 4 2014/10/22 21:24
111 20249 2 2014/10/22 21:39

备注:客户主动删除商品或购买商品,时间分别记录在delete_time和buy_time两个字段,否则记录为空

需求

请在25 分钟内完成下面4 道试题:
1:请写出“计算2014/03/22-2014/04/30 每天的购买客户数、订单量、销售件数、销售额”的
SQL 代码,结果格式要求如下:

日期 购买客户数 订单量 销售件数 销售额
2014/3/22 1 1 3 434
2014/3/30 1 1 2 380
2014/4/11 1 1 6 2,045
2014/4/22 1 1 4 2,375

2:请写出“计算2014 年4 月各品类的销售额、晚上20-24 点销售额”的SQL 代码,结果格式
要求如下:

品类 销售额 20-24点销售额
女装 558 558
男装 1,577 1,197
男鞋 2,285 290

3:请写出“提取2014 年3-5 月销售额排名前三的客户信息(排名/客户号/客户姓名/总销售额
/购买品类)”的SQL 代码,结果格式要求如下:

排名 客户号 客户姓名 总销售额 购买品类
1 222 黎佳 2,755 女鞋、男装、男鞋
2 333 杨峰 2,045 女装、男装、男鞋
3 444 催楠 1,298 女鞋

4:特卖模式下,客户把商品放入购物车后,需在 20 分钟内完成购买,每加入一件新的商品,购物时长(即 20 分钟)将重新计算,若在 20 分钟内无放入购物车行为,购物车内商品会由系统自动释放。请结合购物车表的数据结构,写出计算 2014 年 3 月每日平均每件商品 hold 货时长(即商品的锁定时间)的逻辑和 SQL 代码,结果格式要求如下:

日期 平均hold货时长
2014/3/1
2014/3/2
……

建表导数

$ vi create_table.sql

编辑保存如下内容:

--订单表
drop table if exists table_order;
create table table_order(
  order_id  string 
, user_id string 
, goods_id string
, add_time timestamp 
, price decimal(32,2)
, amount int
, department_id string
) row format delimited fields terminated by '\t';
insert into table_order values ('1236','111','20340','2014-03-22 01:19:00',398.00,1,'1');
insert into table_order values ('1236','111','12432','2014-03-22 01:19:00',18.00 ,2,'2');
insert into table_order values ('1648','333','56235','2014-04-11 21:00:00',399.00,3,'3');
insert into table_order values ('1648','333','42521','2014-04-11 21:00:00',290.00,1,'4');
insert into table_order values ('1648','333','24466','2014-04-11 21:00:00',279.00,2,'1');
insert into table_order values ('2060','222','25948','2014-03-30 13:21:00',190.00,2,'2');
insert into table_order values ('2472','222','20942','2014-04-22 09:59:00',380.00,1,'3');
insert into table_order values ('2472','222','98303','2014-04-22 09:59:00',299.00,1,'4');
insert into table_order values ('2472','222','39555','2014-04-22 09:59:00',848.00,2,'4');
insert into table_order values ('2884','444','20249','2014-05-07 17:53:00',599.00,1,'2');
insert into table_order values ('2884','444','39523','2014-05-07 17:53:00',699.00,1,'2');

--品类表
drop table if exists table_department;
create table table_department(
  department_id   string 
, department_name string 
) ;
insert into table_department values ('1','女装');
insert into table_department values ('2','女鞋');
insert into table_department values ('3','男装');
insert into table_department values ('4','男鞋');

--客户表
drop table if exists table_user;
create table table_user (
  user_id string
, user_name string
);
insert into table_user values('111','张敏');
insert into table_user values('222','黎佳');
insert into table_user values('333','杨峰');
insert into table_user values('444','催楠');

--购物车表
drop table if exists table_cart;
create table table_cart(
  user_id string
, goods_id string
, amount int
, add_time timestamp
, delete_time timestamp
, buy_time timestamp
);
insert into table table_cart values ('111','56235',2,'2014-10-22 10:01:00',null,'2014-10-22 10:20:00');
insert into table table_cart values ('111','24466',1,'2014-10-22 10:21:00','2014-10-22 10:29:00',null);	
insert into table table_cart values ('111','25948',3,'2014-10-22 10:24:00',null,null);
insert into table table_cart values ('111','39555',1,'2014-10-22 21:20:00','2014-10-22 21:26:00',null);	
insert into table table_cart values ('111','98303',4,'2014-10-22 21:24:00',null,null);
insert into table table_cart values ('111','20249',2,'2014-10-22 21:39:00',null,null);

$ hive -f create_table.sql

执行建表导数脚本

查询脚本

需求1

–1.计算 2014/03/22-2014/04/30 每天的购买客户数、订单量、销售件数、销售额

select 
  count(distinct user_id) as user_id_num
 ,count(distinct order_id) as order_id_num 
 ,sum(amount) as amount_num
 ,sum(price*amount) as total_price
from 
 table_order
where date(add_time) 
between '2014-03-22' and '2014-04-30';

查询结果

user_id_num order_id_num amount_num total_price
3 4 15 5234

需求2

–2.计算 2014 年 4 月各品类的销售额、晚上 20-24 点销售额

select 
   b.department_name as department_name
 , sum(a.price*a.amount) as total_sale
 , sum(if(hour(a.add_time) between 20 and 24,a.price*a.amount,0)) as evening_total_sale
from 
 table_order a
join table_department b
on a.department_id = b.department_id
group by b.department_name;

查询结果

department_name total_sale_price evening_total_sale
女装 956 558
女鞋 1714 0
男装 1577 1197
男鞋 2285 290

需求3

–提取 2014 年 3-5 月销售额排名前三的客户信息(排名/客户号/客户姓名/总销售额/购买品类)

select
    t1.rn as rn
  , t1.user_id  as user_id
  , t2.user_name as user_name
  , t1.total_sale as total_sale
  , t1.department_name_col as department_name_col
from 
  (select 
        a.user_id
      , sum(price*amount) as total_sale
      , concat_ws('、',collect_set(b.department_name)) AS department_name_col
      , row_number() over(order by sum(price*amount) desc) as rn
  from 
       table_order a
  left join table_department b
  on a.department_id = b.department_id
  group by 
     a.user_id
  ) t1 --通过客户id将品类数据行转列
left join table_user t2 --取客户名称
on t1.user_id = t2.user_id
where t1.rn <= 3;

查询结果

需求4

–计算 2014 年 3 月每日平均每件商品 hold 货时长(即商品的锁定时间)

select
    to_date(add_time) as dt
  , sum(duration_time)/(count(1)*60.00) as per_duration_min --平均时长(分钟)
from
  (select
      add_time
    , unix_timestamp(coalesce(delete_time,buy_time,each_end_time)) - unix_timestamp(add_time) as duration_time -- 每条的时长
   from
       (select
          user_id
        , add_time
        , delete_time
        , buy_time
        , min(cast(end_time as timestamp)) over(partition by user_id order by add_time desc rows between unbounded preceding and current row) as each_end_time --取每批的自动清空时间
       from
           (
           select 
                 user_id
               , add_time
               , delete_time
               , buy_time
               , case when unix_timestamp(next_time) - unix_timestamp(add_time) > 20*60 or next_time is null then from_unixtime(unix_timestamp(add_time)+ 20*60) end as end_time --只对分组最后一条打上结束时间
           from
               (select
                   user_id
                 , add_time
                 , delete_time
                 , buy_time
                 , lead(add_time) over(partition by user_id order by add_time) as next_time --下一条商品加入时间
               from table_cart
               ) t1
           )t2
       )t3
  )t4
group by to_date(add_time);

查询结果

dt per_duration
2014/10/22 18

猜你喜欢

转载自blog.csdn.net/u012955829/article/details/106697153