题目重点:筛副本数严格大于10的书,再按给定lifetime value取前三,说明指标缺失。
题意与假设
这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。
- 训练book一行书名实体含已给lifetime_value,copy一行物理副本;超过10是>10,exact3、tie按bookId。题面未定义LTV公式,本例不编造“借阅数×单价”。
解题路线
- 先按copy.book_id COUNT得到copy_count并HAVING COUNT(*)>10,再join book取lifetime_value排名。先筛资格再LIMIT,不能先全书Top3后筛导致少行且漏次优。
- 这里lifetime_value视为提供的metric字段;若需从交易计算,要确认收入/成本/时间折现与退款,不依据字段名假定公式。
- 副本数是否含报废/丢失/库存历史需核对,本训练全copy计数。若仅active需在copy聚合WHERE筛状态,与LTV历史期无直接等价。
- 分离聚合防其他一对多loan/reservation连接放大copy count;不要COUNT贷款次数当副本数。Tie包含全部并列第三与exact3不同,当前固定exact3。
手动走一遍
书A LTV100但copy10不合格,B90 copy11合格。先取全体前三再筛A会漏后续合格书,应从全部合格书中排序。正好10与11是关键边界。
SQL 参考实现
下面的代码按上文假设实现,适合本地运行并追加自己的测试用例。
代码区可横向滚动;使用键盘时,先聚焦代码区再按方向键查看。
-- Training: book(book_id PK,lifetime_value), copy(copy_id PK,book_id,condition).
-- lifetime_value is a provided metric, not fabricated loan revenue formula.
-- More than 10 physical copies, exact top3; tie book_id.
WITH copies AS (
SELECT book_id,COUNT(*) AS copy_count FROM copy GROUP BY book_id HAVING COUNT(*)>10
)
SELECT b.book_id,b.lifetime_value,c.copy_count
FROM book b JOIN copies c ON c.book_id=b.book_id
ORDER BY b.lifetime_value DESC,b.book_id
LIMIT 3;
复杂度
O(C)副本聚合,B书join和资格筛选,候选排序O(B log B)或TopK优化;copy/book主键索引与实际计划决定。聚合状态O(B),结果最多3。
易错点与追问
容易失分的边界
- 把>10写>=10。
- 先Top3后过滤资格。
- 无公式就凭空计算LTV并称题目要求。
继续深挖
- 题目要求包含并列第三时,RANK/DENSE_RANK与ROW_NUMBER怎样选择?
- LTV可负或NULL时,排名/NULL政策要怎样明确?
