如何通过SQL筛选指定日期范围内全程可借阅的书籍数据
实现指定日期范围内全可用书籍的SQL查询
当然可以实现这个需求!这是一个典型的「先筛选合格书籍,再提取对应数据」的场景,下面给你两种实用的SQL实现方案:
方案一:固定日期范围天数(适合已知天数的场景)
如果已经明确日期范围是3天(2019-10-11至2019-10-13),可以直接用硬编码的天数来校验:
SELECT t.* FROM your_table t -- 关联筛选出的合格书籍列表 JOIN ( SELECT name FROM your_table WHERE date BETWEEN '2019-10-11' AND '2019-10-13' GROUP BY name -- 双重校验: -- 1. 该书籍在日期范围内每天都有记录(总条数等于天数) -- 2. 该书籍在范围内没有任何不可用的记录 HAVING COUNT(*) = 3 AND SUM(CASE WHEN available = 'N' THEN 1 ELSE 0 END) = 0 ) valid_books ON t.name = valid_books.name WHERE t.date BETWEEN '2019-10-11' AND '2019-10-13';
方案二:动态计算日期范围天数(适合灵活日期场景)
如果日期范围可能变化,不想硬写天数,可以用日期函数动态计算范围天数,适配更通用的场景:
SELECT t.* FROM your_table t JOIN ( SELECT name FROM your_table WHERE date BETWEEN '2019-10-11' AND '2019-10-13' GROUP BY name HAVING -- 动态计算日期范围的总天数,确保书籍每天都有记录 COUNT(DISTINCT date) = DATEDIFF('2019-10-13', '2019-10-11') + 1 -- 确保没有不可用的记录 AND SUM(CASE WHEN available = 'N' THEN 1 ELSE 0 END) = 0 ) valid_books ON t.name = valid_books.name WHERE t.date BETWEEN '2019-10-11' AND '2019-10-13';
核心思路解释
- 子查询筛选合格书籍:通过
GROUP BY name对指定日期范围内的数据分组,用HAVING子句做两个关键校验:- 确保该书籍在日期范围内的每一天都有对应的记录(避免某一天缺失数据但误判为全可用)
- 确保该书籍在范围内没有任何一条
available='N'的记录
- 关联原表取数:将原表和筛选出的合格书籍列表关联,最终只取出这些书籍在指定日期范围内的所有行。
这样就能精准排除像Book_3这种存在不可用日期的书籍,只返回符合要求的Book_1和Book_2的全部对应数据。
内容的提问来源于stack exchange,提问作者Drawio
相关产品推荐
相关产品推荐

