题目描述
(通过次数12,263 | 提交次数25,815,通过率47.50%)
书籍表Books: +----------------+---------+ | Column Name | Type | +----------------+---------+ | book_id | int | | name | varchar | | available_from | date | +----------------+---------+ book_id 是这个表的主键。 订单表Orders: +----------------+---------+ | Column Name | Type | +----------------+---------+ | order_id | int | | book_id | int | | quantity | int | | dispatch_date | date | +----------------+---------+ order_id 是这个表的主键。 book_id 是 Books 表的外键。 你需要写一段 SQL 命令,筛选出过去一年中订单总量少于10本的书籍。 注意:不考虑上架(available from)距今不满一个月 的书籍。并且假设今天是2019-06-23。 下面是样例输出结果: Books 表: +---------+--------------------+----------------+ | book_id | name | available_from | +---------+--------------------+----------------+ | 1 | "Kalila And Demna" | 2010-01-01 | | 2 | "28 Letters" | 2012-05-12 | | 3 | "The Hobbit" | 2019-06-10 | | 4 | "13 Reasons Why" | 2019-06-01 | | 5 | "The Hunger Games" | 2008-09-21 | +---------+--------------------+----------------+ Orders 表: +----------+---------+----------+---------------+ | order_id | book_id | quantity | dispatch_date | +----------+---------+----------+---------------+ | 1 | 1 | 2 | 2018-07-26 | | 2 | 1 | 1 | 2018-11-05 | | 3 | 3 | 8 | 2019-06-11 | | 4 | 4 | 6 | 2019-06-05 | | 5 | 4 | 5 | 2019-06-20 | | 6 | 5 | 9 | 2009-02-02 | | 7 | 5 | 8 | 2010-04-13 | +----------+---------+----------+---------------+ Result 表: +-----------+--------------------+ | book_id | name | +-----------+--------------------+ | 1 | "Kalila And Demna" | | 2 | "28 Letters" | | 5 | "The Hunger Games" | +-----------+--------------------+ 来源:力扣(LeetCode) 链接:https://leetcode.cn/problems/unpopular-books
//测试数据 Create table If Not Exists Books (book_id int, name varchar(50), available_from date); Create table If Not Exists Orders (order_id int, book_id int, quantity int, dispatch_date date); insert into Books (book_id, name, available_from) values ('1', 'Kalila And Demna', '2010-01-01'); insert into Books (book_id, name, available_from) values ('2', '28 Letters', '2012-05-12'); insert into Books (book_id, name, available_from) values ('3', 'The Hobbit', '2019-06-10'); insert into Books (book_id, name, available_from) values ('4', '13 Reasons Why', '2019-06-01'); insert into Books (book_id, name, available_from) values ('5', 'The Hunger Games', '2008-09-21'); insert into Orders (order_id, book_id, quantity, dispatch_date) values ('1', '1', '2', '2018-07-26'); insert into Orders (order_id, book_id, quantity, dispatch_date) values ('2', '1', '1', '2018-11-05'); insert into Orders (order_id, book_id, quantity, dispatch_date) values ('3', '3', '8', '2019-06-11'); insert into Orders (order_id, book_id, quantity, dispatch_date) values ('4', '4', '6', '2019-06-05'); insert into Orders (order_id, book_id, quantity, dispatch_date) values ('5', '4', '5', '2019-06-20'); insert into Orders (order_id, book_id, quantity, dispatch_date) values ('6', '5', '9', '2009-02-02'); insert into Orders (order_id, book_id, quantity, dispatch_date) values ('7', '5', '8', '2010-04-13');
解题思路
题目要求计算出满足下列条件的书籍:
条件1:上架(available from)距今满一个月;
条件2:最近一年订单总量少于10本;
分析上面的条件,条件1可以从Books表计算得出;条件2可以从Orders表计算得出。最后,再计算条件1和条件2结果的交集即可。
不过,因为Orders表中不存在销量为0的书籍,所以还需要对这部分书籍进行特殊处理。
另外,上面的计算步骤也比较复杂。
可以思考是否有相对简洁的写法。
比如,为减少子查询,可以先将Books表和Orders表进行左关联,形成一个大宽表。因为使用的是左关联,也不需要针对销量为0的书籍进行特殊考虑。
而且,如果对SQL的执行顺序很熟的话,不同的筛选条件,可以在合适的阶段进行筛选过滤。也许一句SQL就可以完全实现。
参考SQL
未特别说明的情况下,参考SQL为基于MySQL8.0实现。
select b.book_id, max(b.name) name from Books b left join Orders a on a.book_id = b.book_id and a.dispatch_date >= date_sub('2019-06-23',interval 1 year) where b.available_from <= date_sub('2019-06-23',interval 1 month) group by b.book_id having coalesce(sum(a.quantity),0) < 10;
本站所有内容均为原创,本站保留所有权利。仅允许非商业用途的转载,但必须注明来源网站、作者、来源链接!否则,由此造成的一切后果,由转载方承担!
干货分享、技术提升、面试笔试、学习交流,欢迎关注公众号:xuesql。QQ学习交流群:209942678。