SQL每日练习(一)

题目来源:SQL练习

1.计算商城中2021年每月的GMV

题目描述:

订单总表tb_order_overall(order_id-订单号, uid-用户ID, event_time-下单时间, total_amount-订单总金额, total_cnt-订单商品总件数, status-订单状态)

场景逻辑说明:

用户将购物车中多件商品一起下单时,订单总表会生成一个订单(但此时未付款,status-订单状态为0,表示待付款);
当用户支付完成时,在订单总表修改对应订单记录的status-订单状态为1,表示已付款;
若用户退货退款,在订单总表生成一条交易总金额为负值的记录(表示退款金额,订单号为退款单号,status-订单状态为2表示已退款)。

问题:

请计算商城中2021年每月的GMV,输出GMV大于10w的每月GMV,值保留到整数。GMV为已付款订单和未付款订单两者之和。结果按GMV升序排序。

解答:
(1)GMV为已付款订单和未付款订单两者之和,即用status=0或1进行筛选;
(2)每月的GMV,说明要按月分组输出,根据示例来看还需要对时间的格式做调整,用date_format函数

select date_format(event_time,'%Y-%m') month,sum(total_amount) GMV
from tb_order_overall
where status in (0,1)
group by month
having GMV>100000
order by GMV

知识点:date_format函数

date_format函数的使用
用于以不同的格式显示日期/时间数据,语法DATE_FORMAT(date,format)

格式描述
%Y年,4 位
%y年,2 位
%m月,数值(00-12)
%b缩写月名
%d月的天,数值(00-31)
%e月的天,数值(0-31)

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

题目描述:
商品行为表tb_user_event(uid-用户ID, product_id-商品ID, event_time-行为时间, if_click-是否点击, if_cart-是否加购物车, if_payment-是否付款, if_refund-是否退货退款)

场景逻辑说明:
商品点展比=点击数÷展示数;
加购率=加购数÷点击数;
成单率=付款数÷加购数;退货率=退款数÷付款数,

问题:
请统计2021年10月每个有展示记录的退货率不大于0.5的商品各项指标,当分母为0时整体结果记为0,结果中各项指标保留3位小数,并按商品ID升序排序。

解答:
(1)保留三位小数,用 round
(2)有一堆指标要计算,并赋别名,以group by product_id 按商品分组输出

select product_id,round(sum(if_click)/count(*),3) ctr,
       round(sum(if_cart)/sum(if_click),3) cart_rate,
       round(sum(if_payment)/sum(if_cart),3) payment_rate,
       round(sum(if_refund)/sum(if_payment),3) refund_rate
from tb_user_event
group by product_id
having refund_rate<=0.5
order by product_id

这样在少量的数据中能得到正确的结果,但并不眼睛,还有一些问题没有处理:
(1)没有对时间进行筛选(2021年10月)
(2)未考虑分母可能为0的情况

比较完整的作答:

select product_id, round(click_cnt/show_cnt, 3) as ctr,
    round(IF(click_cnt>0, cart_cnt/click_cnt, 0), 3) as cart_rate,
    round(IF(cart_cnt>0, payment_cnt/cart_cnt, 0), 3) as payment_rate,
    round(IF(payment_cnt>0, refund_cnt/payment_cnt, 0), 3) as refund_rate
from (
    select product_id, COUNT(1) as show_cnt,
        sum(if_click) as click_cnt,
        sum(if_cart) as cart_cnt,
        sum(if_payment) as payment_cnt,
        sum(if_refund) as refund_cnt
    from tb_user_event
    where DATE_FORMAT(event_time, '%Y%m') = '202110'
    group by product_id
) as t_product_index_cnt
where payment_cnt = 0 or refund_cnt/payment_cnt <= 0.5
order by product_id;

生成了一个子表 t_product_index_cnt 进行sum计数,并只选取出规定时间内的记录,这里也用到了 date_format函数,对时间的格式进行处理以便筛选。利用 if 语句处理分母为0的情况。

count(1) count(*) count(列名)的区别
总结一下就是,count(1) count(*) 结果一样,但count(1)速度可能快一些。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值