跳到主要内容

SHEIN大数据面试SQL-SKU级别库存周转天数

⚠️ 待修正

一、题目背景

这道题来自SHEIN的数据分析岗面试。SHEIN是快时尚跨境电商,数据分析师需要从海量业务数据中挖掘洞见。

业务场景:供应链管理相关需求在日常工作中频繁出现,这类型的SQL题是面试高频考点。

一、题目

SHEIN需要监控每个SKU的库存周转效率。库存周转天数 = 期间内平均库存量 / 期间内日均销量。计算2025年6月每个SKU的库存周转天数。

假设有两张表:

  • inventory_snapshot:每日库存快照表
  • daily_sales:每日销量表
-- inventory_snapshot 每日库存快照
+------------+---------+--------+
| snap_date | sku_id | stock |
+------------+---------+--------+
| 2025-06-01 | SKU001 | 500 |
| 2025-06-02 | SKU001 | 480 |
| 2025-06-03 | SKU001 | 460 |
| 2025-06-01 | SKU002 | 300 |
| 2025-06-02 | SKU002 | 280 |
| 2025-06-03 | SKU002 | 250 |
+------------+---------+--------+

-- daily_sales 每日销量表
+------------+---------+--------+
| sale_date | sku_id | qty |
+------------+---------+--------+
| 2025-06-01 | SKU001 | 20 |
| 2025-06-02 | SKU001 | 20 |
| 2025-06-03 | SKU001 | 20 |
| 2025-06-01 | SKU002 | 20 |
| 2025-06-02 | SKU002 | 30 |
| 2025-06-03 | SKU002 | 25 |
+------------+---------+--------+

三、思路分析

  1. 分别按SKU计算平均库存 = avg(stock);
  2. 分别按SKU计算日均销量 = sum(qty) / count(distinct sale_date);
  3. 库存周转天数 = 平均库存 / 日均销量;
  4. 使用 JOIN 或子查询分别聚合再关联。
维度评分
题目难度⭐️⭐️⭐️
题目清晰度⭐️⭐️⭐️⭐️
业务常见度⭐️⭐️⭐️⭐️

四、逐步推导

1.分别计算平均库存和日均销量

执行SQL

select sku_id,
round(avg(stock), 2) as avg_stock,
round(sum(qty) / count(distinct sale_date), 2) as avg_daily_sales
from (
select i.sku_id, i.stock, s.qty, s.sale_date
from inventory_snapshot i
left join daily_sales s
on i.sku_id = s.sku_id and i.snap_date = s.sale_date
where i.snap_date between '2025-06-01' and '2025-06-30'
) t
group by sku_id

查询结果

+---------+-----------+-----------------+
| sku_id | avg_stock | avg_daily_sales |
+---------+-----------+-----------------+
| SKU001 | 480.00 | 20.00 |
| SKU002 | 276.67 | 25.00 |
+---------+-----------+-----------------+

2.计算库存周转天数

执行SQL

select sku_id,
avg_stock,
avg_daily_sales,
round(avg_stock / avg_daily_sales, 1) as turnover_days
from (
select sku_id,
round(avg(stock), 2) as avg_stock,
round(sum(qty) / count(distinct sale_date), 2) as avg_daily_sales
from (
select i.sku_id, i.stock, coalesce(s.qty, 0) as qty, s.sale_date
from inventory_snapshot i
left join daily_sales s
on i.sku_id = s.sku_id and i.snap_date = s.sale_date
where i.snap_date between '2025-06-01' and '2025-06-30'
) t
group by sku_id
) tt

查询结果

+---------+-----------+-----------------+----------------+
| sku_id | avg_stock | avg_daily_sales | turnover_days |
+---------+-----------+-----------------+----------------+
| SKU001 | 480.00 | 20.00 | 24.0 |
| SKU002 | 276.67 | 25.00 | 11.1 |
+---------+-----------+-----------------+----------------+

五、常见坑点

坑1:NULL值的隐式处理 — 聚合函数跳过NULL,窗口函数不跳过。WHERE需显式过滤或用COALESCE替代。

坑2:数据类型不一致导致JOIN失效 — string vs int隐式转换可能触发全表扫描,性能骤降。

六、举一反三

  1. 增加时间维度对比:按天/周/月分组,观察指标的趋势和季节性波动

  2. 增加分组维度:按品类/地区/渠道拆解,发现差异化的业务洞察

  3. 设置预警阈值:在WHERE中加阈值判断,自动筛选异常数据

七、知识点总结

考点说明
多表JOINLEFT JOIN保留主表所有数据,COALESCE处理NULL
GROUP BY + 聚合函数分组聚合是数据分析的基础,配合HAVING筛选分组结果
日期函数DATEDIFF / DATE_ADD / unix_timestamp处理日期运算
NULL值处理NULL在聚合和窗口函数中的差异,COALESCE/NVL的替代方案

八、建表语句和数据插入

点击展开 DDL & DML
--建表语句
CREATE TABLE inventory_snapshot (
snap_date string COMMENT '快照日期',
sku_id string COMMENT 'SKU编码',
stock int COMMENT '当日库存量'
) COMMENT '每日库存快照表';

CREATE TABLE daily_sales (
sale_date string COMMENT '销售日期',
sku_id string COMMENT 'SKU编码',
qty int COMMENT '当日销量'
) COMMENT '每日销量表';

-- 插入数据
insert into inventory_snapshot(snap_date, sku_id, stock) values
('2025-06-01','SKU001',500),
('2025-06-02','SKU001',480),
('2025-06-03','SKU001',460),
('2025-06-01','SKU002',300),
('2025-06-02','SKU002',280),
('2025-06-03','SKU002',250);

insert into daily_sales(sale_date, sku_id, qty) values
('2025-06-01','SKU001',20),
('2025-06-02','SKU001',20),
('2025-06-03','SKU001',20),
('2025-06-01','SKU002',20),
('2025-06-02','SKU002',30),
('2025-06-03','SKU002',25);
📱关注公众号

「数据仓库技术」文章同步更新,不错过每一篇干货

微信公众号二维码
💬加群交流

备注「数据仓库技术」加入社群,每日一道大厂SQL真题

交流微信二维码

你可能还想看