Leetcode1098. 不受欢迎的书(中等)

题目
书籍表 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" |
+-----------+--------------------+

生成数据

CREATE TABLE Books(
book_id        INT,
NAME           VARCHAR(20),
available_from DATE,
PRIMARY KEY(book_id));

CREATE TABLE Orders3(
order_id       INT,     
book_id        INT,     
quantity       INT,     
dispatch_date  DATE,
PRIMARY KEY(order_id));

INSERT INTO Books VALUE(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');

INSERT INTO Orders3 VALUE(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');

解答
筛选出过去一年中订单总量 少于10本 的 书籍 。
注意:不考虑 上架(available from)距今 不满一个月 的书籍。并且 假设今天是 2019-06-23

先去掉上架(available from)距今 不满一个月 的书籍

SELECT *
FROM Books AS B
WHERE B.available_from < '2019-05-23';

再选出过去一年的订单

SELECT O.`book_id`, O.`quantity`
FROM orders3 AS O
WHERE O.`dispatch_date` BETWEEN '2018-06-23' AND '2019-06-23';

两表连接

SELECT *
FROM (SELECT B.`book_id`, B.`name`
FROM Books AS B
WHERE B.available_from < '2019-05-23') tmp1
LEFT JOIN (SELECT O.`book_id`, O.`quantity`
FROM orders3 AS O
WHERE O.`dispatch_date` BETWEEN '2018-06-23' AND '2019-06-23') tmp2
ON tmp1.book_id = tmp2.book_id

分组求和

SELECT tmp1.book_id, tmp1.name, SUM(tmp2.quantity)
FROM (SELECT *
FROM Books AS B
WHERE B.available_from < '2019-05-23') tmp1
LEFT JOIN (SELECT *
FROM orders3 AS O
WHERE O.`dispatch_date` BETWEEN '2018-06-23' AND '2019-06-23') tmp2
ON tmp1.book_id = tmp2.book_id
GROUP BY tmp1.book_id;

这里的NULL需要注意 其实是0的意思 后边的判断需要注意或者这里用IFNULL进行处理

SELECT tmp1.book_id, tmp1.name
FROM (SELECT *
FROM Books AS B
WHERE B.available_from < '2019-05-23') tmp1
LEFT JOIN (SELECT *
FROM orders3 AS O
WHERE O.`dispatch_date` BETWEEN '2018-06-23' AND '2019-06-23') tmp2
ON tmp1.book_id = tmp2.book_id
GROUP BY tmp1.book_id
HAVING (SUM(tmp2.quantity) < 10) OR (SUM(tmp2.quantity) IS NULL);

你可能感兴趣的:(Leetcode1098. 不受欢迎的书(中等))