在简化的租赁系统中,有三种关系:
- 书籍:id,标题,描述
- 复制:id,book_id
- 预订:id,copy_id,rent_from,rent_until
每本书都有许多副本。如果客户租用了一本书,则会选择一份可用的副本,并创建相应的预订记录。
现在我的问题是:客户选择了一本书,他/她想租。系统需要检查在给定的租赁期内哪些副本可用。
查询可用副本的最优雅、最快捷的方法是什么?
基本上,一步一步地进行以下操作:
- 选择相应书籍的所有副本
- 选择这些副本指定期间内的所有预订
- 检查所选预订中不包括该书的哪些副本。如果所有的书都包括在内,那么这本书在规定的时间内是不可出租的
第三步让我头疼。如何在SQL中做到这一点?我甚至可以在一个优雅的查询中执行所有三个步骤吗?
假设您有bookid。您正在寻找:
select c.*
from copies c
where not exists (select 1
from booking b
where b.copy_id = c.id and
b.rent_until >= @PeriodStart and b.rent_from <= @PeriodEnd
);
这是在检查重叠的时间段。如果预订在时段开始后结束,并且预订在时段结束前开始,则存在重叠。比较可能是<
和>
,这取决于一本书是否可以在rent_until
日期出租,或者是否必须等到第二天。