牛客SQL 大厂面试真题 某宝店铺分析 5套代码及解析

5.某宝店铺分析(电商模式)

SQL180 某宝店铺的SPU数量

select style_id,
count(item_id) as SPU_num
from product_tb
group by style_id
order by SPU_num desc

SQL181 某宝店铺的实际销售额与客单价

select
sum(sales_price) as sales_total,
round(sum(sales_price)/count(distinct user_id),2) as per_trans
from sales_tb

SQL182 某宝店铺折扣率

  1. 题目中sales_price是结算金额,不要像我一样把他当成单个产品的售出金额,又给他乘一遍sales_num)
select
round(sum(sales_price)/sum(tag_price*sales_num)*100,2) as discount_rate
from product_tb
join sales_tb using(item_id)

SQL183 某宝店铺动销率与售罄率

  1. 第一次是这么写的,但是结果都偏小。 原因是:库存表与销售表连接之后对应的每条sku的库存记录不是唯一的,inventory会有重复的计算,直接计算结果偏小。举个例子,sales_tb里有两个A003,就会返回两个A003对应的inventory,所以需要去重。
select style_id,
round(sum(sales_num)/(sum(inventory)-sum(sales_num))*100,2) as pin_rate,
round(sum(sales_price)/sum(tag_price*inventory)*100,2) as sell_through_rate
from product_tb
left join sales_tb using(item_id)
group by style_id
order by style_id
  1. 下面是正确的写法,先通过item_id进行分组,求出每个item_id下售出的商品数量以及GMV,再通过style_id进行分组,求出每个style_id下的商品动销率和售空率
select style_id,
round(sum(num)/(sum(inventory)-sum(num))*100,2) as pin_rate,
round(sum(GMV)/sum(tag_price*inventory)*100,2) as sell_through_rate
from product_tb as a
join (
    select item_id,
    sum(sales_num) as num,
    sum(sales_price) as GMV
    from sales_tb 
    group by item_id
    ) as b
on a.item_id=b.item_id
group by style_id
order by style_id
  1. 通过对inventory去重,也可以得到正确答案 。但是当product_tb表中存在多个产品的inventory数量相同时,结果就会是错的。
select style_id,
round(sum(sales_num)/(sum(distinct inventory)-sum(sales_num))*100,2),
round(sum(sales_price)/sum(distinct((tag_price*inventory)))*100,2)
from product_tb 
join sales_tb using(item_id)
group by style_id

SQL184 某宝店铺连续2天及以上购物的用户及其对应天数

  1. 本题类似于167题的算法,难点在于计算出连续的天数。

  2. 解题思路:首先对日期进行排序,其次判断连续日期,并查询统计连续天数>=2的用户即可

  3. 判断连续日期的方法:
    第一步,对日期去重后进行排序(或者直接用dense_rank进行排序,这是因为dense_rank对于重复的日期,在排序上是相同的,如果是同一天,所以不用再考虑重复日期的影响);
    第二步,日期减去排序对应序号的天数如果是一个相同的值,则说明这些日期就是连续的。
    第三步,对连续的日期再次排序就得到了最大的连续数列。
    在这里插入图片描述

  4. 判断连续日期,并查询统计连续天数>=2的用户的方法:
    使用date_sub()函数并聚合后判断日期连续
    如果sales_date 减去rk(天)是相同的日期,则说明他们这些天都是连续的日期(所以要使用dense_rank()并且对日期进行去重,不然重复的日期也会被记作连续的天数)。
    在这里插入图片描述

  5. count(1)和count()之间没有区别,因为count()count(1)都不会去过滤空值。但count(1)的计算效率要高于 count(*)

select user_id,
count(1) as days_count
from (
    select distinct sales_date,
    user_id,
    dense_rank()over(partition by user_id order by sales_date)rk 
    FROM sales_tb
    )t1
group by user_id,
date_sub(sales_date,interval rk day) 
HAVING count(1)>=2;

猜你喜欢

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