Data Engineer / Data Scientist · DE / SQL

Meta 租车库存SQL:某日结束时租出比例

按城市和车型算已租车辆/库存,明确车辆粒度、租赁区间与重复事实去重。

题目重点:按城市和车型算已租车辆/库存,明确车辆粒度、租赁区间与重复事实去重。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 示例schema是训练自定义:location、car、fct_rental,car.current location与active代表同一天库存快照;历史车型/迁移需另用有效期维表。
  • 按D日结束租出定义pickup_date≤D且dropoff_date>D,半开交接口径;这与前一闭日期预订训练不同。取消不计租出,按distinct car而非rental行数统计。

解题路线

  1. 先筛当日confirmed租赁,SELECT DISTINCT car_id得到占用车辆集。租赁事实一车多单不能直接join后COUNT(*)当库存,否则分母被放大。
  2. 从库存car出发join location,再left join租出车集,按city/car_size聚合。COUNT(*)是活库存车数,COUNT(r.car_id)是其中租出数,1.0确保非整数除法。
  3. 为什么从库存出发?只有出租记录的inner join会漏零出租车型组,比例分母必须包含未出租车。active过滤口径需要与日期一致。
  4. 同城市多个location合并到城市结果;若要求逐门店则group by location_id/size后展示city,不混同粒度。跨门店租还应以车辆当日库存归属,而非任意订单取车location当分母。
  5. 若“到某天为止租过”是累计出租,则筛pickup≤D不同于当天仍在租;先复述时点口径再写条件。DDL未给原表,当前命名与字段不能当作唯一真实输入。

手动走一遍

A城small库存3辆:一辆昨天取明天还、一辆今天还、一辆未租。按D日结束只有第一辆仍占用,比例1/3。第一辆重复两行confirmed也仍计1;取消订单不占用。

SQL 参考实现

下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。

代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。

-- Training schema:
-- location(location_id PK, city), car(car_id PK, location_id, car_size, active)
-- fct_rental(rental_id PK, car_id, pickup_date ISO, dropoff_date ISO, status)
-- Inventory is active cars in assigned location at the same snapshot.
-- End-of-day D: pickup_date <= D AND dropoff_date > D (handoff half-open).
-- Cancelled rentals excluded; DISTINCT car_id prevents overlapping fact duplicates.
WITH rented AS (
  SELECT DISTINCT car_id
  FROM fct_rental
  WHERE status = 'confirmed'
    AND pickup_date <= :day AND dropoff_date > :day
)
SELECT l.city, c.car_size,
       COUNT(*) AS inventory,
       COUNT(r.car_id) AS rented_cars,
       1.0 * COUNT(r.car_id) / NULLIF(COUNT(*), 0) AS rented_ratio
FROM car c
JOIN location l ON l.location_id = c.location_id
LEFT JOIN rented r ON r.car_id = c.car_id
WHERE c.active = 1
GROUP BY l.city, c.car_size
ORDER BY l.city, c.car_size;

复杂度

查询计划基线扫描car与租赁事实,DISTINCT需hash/sort O(R)预期或O(R log R),join聚合按C+R量级。car_id、状态/日期与历史partition可帮助筛选;不能笼统宣称SQL总O(1)。

易错点与追问

容易失分的边界

  • join order后COUNT(*)作为库存会重复车行。
  • pickup≤D但没有dropoff限制会算累计历史出租而非当前占用。

继续深挖

  • 零库存组要不要显示NULL/0?需要独立city-size维表left join,当前只输出存在库存的组。
  • 若车今天跨城市迁移,怎样用SCD有效期给库存归属?
✓已复制微信号!