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