题目描述

(通过次数3,568 | 提交次数4,992,通过率71.47%)

表:Boxes
+--------------+------+
| Column Name  | Type |
+--------------+------+
| box_id       | int  |
| chest_id     | int  |
| apple_count  | int  |
| orange_count | int  |
+--------------+------+
box_id 是该表的主键。
chest_id 是 chests 表的外键。
该表包含大箱子 (box) 中包含的苹果和橘子的个数。每个大箱子中可能包含一个小盒子 (chest) ,小盒子中也包含若干苹果和橘子。

表:Chests
+--------------+------+
| Column Name  | Type |
+--------------+------+
| chest_id     | int  |
| apple_count  | int  |
| orange_count | int  |
+--------------+------+
chest_id 是该表的主键。
该表包含小盒子的信息,以及小盒子中包含的苹果和橘子的个数。

编写 SQL 语句,查询苹果和橘子的总个数。如果大箱子中包含小盒子,还应当包含小盒子中苹果和橘子的个数。
以任意顺序返回结果表。

查询结果的格式如下示例所示。
示例 1:
输入:
Boxes 表:
+--------+----------+-------------+--------------+
| box_id | chest_id | apple_count | orange_count |
+--------+----------+-------------+--------------+
| 2      | null     | 6           | 15           |
| 18     | 14       | 4           | 15           |
| 19     | 3        | 8           | 4            |
| 12     | 2        | 19          | 20           |
| 20     | 6        | 12          | 9            |
| 8      | 6        | 9           | 9            |
| 3      | 14       | 16          | 7            |
+--------+----------+-------------+--------------+
Chests 表:
+----------+-------------+--------------+
| chest_id | apple_count | orange_count |
+----------+-------------+--------------+
| 6        | 5           | 6            |
| 14       | 20          | 10           |
| 2        | 8           | 8            |
| 3        | 19          | 4            |
| 16       | 19          | 19           |
+----------+-------------+--------------+
输出:
+-------------+--------------+
| apple_count | orange_count |
+-------------+--------------+
| 151         | 123          |
+-------------+--------------+
解释:
大箱子 2 中有 6 个苹果和 15 个橘子。
大箱子 18 中有 4 + 20 (在小盒子中) = 24 个苹果和 15 + 10 (在小盒子中) = 25 个橘子。
大箱子 19 中有 8 + 19 (在小盒子中) = 27 个苹果和 4 + 4 (在小盒子中) = 8 个橘子。
大箱子 12 中有 19 + 8 (在小盒子中) = 27 个苹果和 20 + 8 (在小盒子中) = 28 个橘子。
大箱子 20 中有 12 + 5 (在小盒子中) = 17 个苹果和 9 + 6 (在小盒子中) = 15 个橘子。
大箱子 8 中有 9 + 5 (在小盒子中) = 14 个苹果和 9 + 6 (在小盒子中) = 15 个橘子。
大箱子 3 中有 16 + 20 (在小盒子中) = 36 个苹果和 7 + 10 (在小盒子中) = 17 个橘子。
苹果的总个数 = 6 + 24 + 27 + 27 + 17 + 14 + 36 = 151
橘子的总个数 = 15 + 25 + 8 + 28 + 15 + 15 + 17 = 123

来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/count-apples-and-oranges
//测试数据
Create table If Not Exists Boxes (box_id int, chest_id int, apple_count int, orange_count int);
Create table If Not Exists Chests (chest_id int, apple_count int, orange_count int);

insert into Boxes (box_id, chest_id, apple_count, orange_count) values ('2', null, '6', '15');
insert into Boxes (box_id, chest_id, apple_count, orange_count) values ('18', '14', '4', '15');
insert into Boxes (box_id, chest_id, apple_count, orange_count) values ('19', '3', '8', '4');
insert into Boxes (box_id, chest_id, apple_count, orange_count) values ('12', '2', '19', '20');
insert into Boxes (box_id, chest_id, apple_count, orange_count) values ('20', '6', '12', '9');
insert into Boxes (box_id, chest_id, apple_count, orange_count) values ('8', '6', '9', '9');
insert into Boxes (box_id, chest_id, apple_count, orange_count) values ('3', '14', '16', '7');

insert into Chests (chest_id, apple_count, orange_count) values ('6', '5', '6');
insert into Chests (chest_id, apple_count, orange_count) values ('14', '20', '10');
insert into Chests (chest_id, apple_count, orange_count) values ('2', '8', '8');
insert into Chests (chest_id, apple_count, orange_count) values ('3', '19', '4');
insert into Chests (chest_id, apple_count, orange_count) values ('16', '19', '19');

解题思路

这道题,官方题目的描述有误:查询每个大箱子中苹果和橘子的个数。
而实际上是要求:查询苹果和橘子的总数。
根据题目描述,我们有一些大箱子(Boxes),大箱子里放的有苹果、橘子、小箱子(Chests:可以没有,但如果有的话,最多只有一个)。
我本来认为,一个小箱子只会放在一个大箱子里,所以把大箱子和小箱子里所有的苹和橘子加起来就可以了。
但从样例数据来看,可以看到6号小箱子在8号、20号大箱子都出现过,而且在计算总数时需要重复计算。
那么,就需要先将每个大箱子对应的小箱子关联出来,再汇总统计。
因为大箱子中可以不放小箱子,或最多放一个小箱子,可以使用LEFT JOIN关联,然后使用SUM汇总即可。

参考SQL

未特别说明的情况下,参考SQL为基于MySQL8.0实现。

select
    sum(a.apple_count+coalesce(b.apple_count,0)) apple_count,
    sum(a.orange_count+coalesce(b.orange_count,0)) orange_count
from Boxes a
left join Chests b
on a.chest_id=b.chest_id;

picture loss