牛客SQL 大厂面试真题 某东商城 6套代码及解析

3.电商场景(某东商城)

SQL168 计算商城中2021年每月的GMV

select 
date_format(event_time,'%Y-%m') as month,
round(sum(total_amount),0) as GMV
from tb_order_overall
where year(event_time) ='2021' and status!=2
group by month
having GMV>100000
order by GMV

SQL169 统计2021年10月每个退货率不大于0.5的商品各项指标

select
    product_id,
    round(sum(if_click)/count(*),3) as ctr,
    round(if(sum(if_click)>0,sum(if_cart)/sum(if_click),0),3) as cart_rate,
    round(if(sum(if_cart)>0,sum(if_payment)/sum(if_cart),0),3) as payment_rate,
    round(if(sum(if_payment)>0,sum(if_refund)/sum(if_payment),0),3) as refund_rate
from tb_user_event
where date_format(event_time,'%Y-%m')='2021-10'
group by product_id
having refund_rate<=0.5
order by product_id

SQL170 某店铺的各商品毛利率及店铺整体毛利率
(1.为什么union all 上下的两个查询要加括号?
不加括号的话,系统默认为最后一个order by是两个表连接后 再进行排序,这样子就会把 “店铺汇总” 排到最后一行。
2.为什么是 having profit_rate > 24.9 而不是 having profit_rate > 24.9%
profit_rate是一个数字,只是最外面才对profit_rate加上了%,在()里面时是个数字
3.为什么union all 上面 和下面 求毛利率的公式不一样?一旦上下同使用一样的毛利率求导公式,就会报错?
通过控制变量法,
将上下两个毛利率计算公式交换位置,结果发现可以通过测试。
两个毛利率计算公式不同时,将下面的毛利率的名称profit_rate改为其他名称,也可以通过测试。
两个毛利率计算公式相同时,将下面的毛利率的名称profit_rate改为其他名称,不可以通过测试。
这就说明问题不出于公式,而是可能在union all 的使用规则上。
我猜测,可能是union all 不可以连接计算方式一样的两个列。

(
select 
'店铺汇总' as product_id,
concat(round((1-sum(in_price*cnt)/sum(price*cnt))*100,1),'%') as profit_rate
from tb_order_detail
join tb_order_overall using(order_id)
join tb_product_info using(product_id)
where date(event_time)>='2021-10-01'
and shop_id='901'
and status=1
)

union all

(
select 
product_id,
concat(round((sum((price-in_price)*cnt)/sum(price*cnt))*100,1),'%') as profit_rate
from tb_order_detail
join tb_order_overall using(order_id)
join tb_product_info using(product_id)
where date(event_time)>='2021-10-01'
and shop_id='901'
and status=1
group by product_id
having profit_rate > 24.9
order by product_id
)

SQL171 零食类商品中复购率top3高的商品
(1. where 中不能使用别名作为判断条件
https://blog.csdn.net/weixin_28007513/article/details/114770136
2.本题的难点在于怎么判定哪些商品是第二次买的,
首先在子查询中,通过对商品和客户进行聚类,用count可以在表上检索出每个商品对应的客户。
再在母查询中使用sum和if,如果购买了两次及以上,则记为1,否则记为0,除以总共的行数,即为每个产品的复购率。)

select 
product_id,
round(sum(if(cnt>=2,1,0))/count(*),3) as repurchase_rate 
from(
    select 
    product_id,
    uid,
    count(uid) as cnt 
    from tb_order_detail
    left join tb_order_overall using(order_id)
    left join tb_product_info using(product_id)
    where datediff((select max(event_time) from tb_order_overall),event_time)<90 
    and tag='零食'
    group by product_id,uid
    ) as a
group by product_id
order by repurchase_rate desc,product_id 
limit 3

SQL172 10月的新户客单价和获客成本
(注意:sum(price*cnt) - sum(distinct total_amount) as diff 中,不可以去掉 sum 或 distinct 任何一个,否则就会违背SQL的 **“出现在select后的字段(除了聚合的字段以外SUM,AVG,MAX,MIN)都必须要在group中”**的规则。
如果想去掉sum 和 distinct ,使total_amount脱离 sum,可以把total_amount放在group by 之后,代码如下所示)

select 
	round(avg(a_amount),1) as avg_amount,
	round(avg(diff),1) as avg_cost
from(
    select
		order_id,
		avg(total_amount) as a_amount,
		sum(price*cnt) - sum(distinct total_amount) as diff
	from tb_order_overall
	left join tb_order_detail using(order_id)
	where month(event_time)='10' 
    and (uid,event_time) in (select uid,min(event_time) from tb_order_overall group by uid) 
    group by order_id
    )as a
select 
	round(avg(a_amount),1) as avg_amount,
	round(avg(diff),1) as avg_cost
from(
    select
		order_id,
		avg(total_amount) as a_amount,
		(sum(price*cnt) - total_amount) as diff
	from tb_order_overall
	left join tb_order_detail using(order_id)
	where month(event_time)='10' 
    and (uid,event_time) in (select uid,min(event_time) from tb_order_overall group by uid) 
    group by order_id,total_amount
    )as a

SQL173 店铺901国庆期间的7月动销率和滞销率
( 1. 通过dt 将三个表连接起来,
t 表和 t2 表的 dt完全相同,
t 表和 t1表 只在相差7天时,才可进行连接。
2. t 表用于限定时间条件,
t1 表用于计算有下单的商品的总数,
t2 表用于计算所有商品的数量。
最后用一个查询的表格,将上面三个表格结合起来,找到想要的数据。
3.在表链接时,可以加入限定条件,以得到想要的结果,具体参考t1 表。

with t as # 取日期 10-01 到 10-03
(select 
date(event_time) as dt
from tb_order_overall 
where date(event_time) between '2021-10-01' and '2021-10-03'),
 
t1 as # 901商店已成交订单中,每个下单日期里的 product_id
(select 
date(event_time) dt,
tod.product_id
FROM tb_order_detail tod 
JOIN tb_order_overall too ON tod.order_id = too.order_id and status = 1
JOIN tb_product_info tpi ON tod.product_id = tpi.product_id and shop_id = '901'),
                          
t2 as # 计算 每个日期下 901商店的 在售商品总数
(select 
date(event_time) as dt,
COUNT(DISTINCT product_id) as sum_product
FROM tb_product_info,tb_order_overall
where shop_id = '901'
group by dt)
 
select t.dt, 
round(count(distinct t1.product_id) / sum_product ,3) as sale_rate, 
ROUND(1- (count(distinct t1.product_id) / sum_product ),3) as unsale_rate
from t 
left join t1 ON datediff(t.dt,t1.dt) between 0 and 6 
JOIN t2 on t.dt = t2.dt
group by t.dt
ORDER by t.dt 

猜你喜欢

转载自blog.csdn.net/qq118640594X/article/details/127378445