Data Engineer · DE / SQL

Meta 图书馆SQL:状态良好且未归还的副本

按物理书副本统计condition good且存在未归还借阅,避免历史借阅连接重复。

题目重点:按物理书副本统计condition good且存在未归还借阅,避免历史借阅连接重复。

题意与假设

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

  • 题目未提供DDL,训练copy一行物理副本、loan一行借阅;未归还returned_at NULL,condition为副本当前状态。若books指不同书名而非副本,输出需COUNT DISTINCT book_id。

解题路线

  1. 从copy过滤condition good,用EXISTS检查同copyId是否有open loan。EXISTS只决定是否存在,不把多个历史loan行乘进count。
  2. 正常业务一个copy最多一个open loan,应有约束/质量检查;查询存在性仍不会因异常重复open行倍增,但这不等于数据异常可忽略。
  3. 当前good与借出时good不同:需要历史状态时copy_condition有效期关联借阅时间。题目只说good没有给时点,本练习使用当前状态并明示。
  4. 尚未借出不等于未归还:完全无loan的copy不能被算入。returned_at NULL在left join空行也会成立,所以先EXISTS而不以空右表判断。

手动走一遍

copy1 good有两条open loan异常、copy2 good从未借、copy3 damaged有open loan、copy4 good已还,按本训练只计copy1一次。数书名版本可能合并不同copy,须另定。

SQL 参考实现

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

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

-- Training: copy(copy_id PK,book_id,condition), loan(loan_id PK,copy_id,returned_at).
-- Count physical copies in good CURRENT condition with any open loan.
-- EXISTS avoids repeated historical loan rows multiplying copy count.
SELECT COUNT(*) AS good_unreturned_copies
FROM copy c
WHERE c.condition='good'
  AND EXISTS (SELECT 1 FROM loan l WHERE l.copy_id=c.copy_id AND l.returned_at IS NULL);

复杂度

copy扫描C,loan(copy_id,returned_at)索引可支持存在查询,近似O(C log L)探测或优化semi-join计划;无索引最坏多次扫描。不要将SQL有COUNT就标常数时间。

易错点与追问

容易失分的边界

  • LEFT JOIN空行returned_at NULL把从未借的copy算未归还。
  • 借阅历史join直接COUNT(*)重复副本。

继续深挖

  • 如果按某日未还,应以borrowed_at≤D且(returned_at>D或NULL)定历史状态。
  • 重复open loan如何在数据质量层报告而不修改题目计数口径?
✓已复制微信号!