1. 力扣1571:仓库经理
1.1 题目:
表: Warehouse
+--------------+---------+ | Column Name | Type | +--------------+---------+ | name | varchar | | product_id | int | | units | int | +--------------+---------+ (name, product_id) 是该表主键(具有唯一值的列的组合). 该表的行包含了每个仓库的所有商品信息.
表: Products
+---------------+---------+ | Column Name | Type | +---------------+---------+ | product_id | int | | product_name | varchar | | Width | int | | Length | int | | Height | int | +---------------+---------+ product_id 是该表主键(具有唯一值的列). 该表的行包含了每件商品以英尺为单位的尺寸(宽度, 长度和高度)信息.
编写解决方案报告每个仓库的存货量是多少立方英尺。
返回结果没有顺序要求。
返回结果格式如下例所示。
示例 1:
输入: Warehouse 表
: +------------+--------------+-------------+ | name | product_id | units | +------------+--------------+-------------+ | LCHouse1 | 1 | 1 | | LCHouse1 | 2 | 10 | | LCHouse1 | 3 | 5 | | LCHouse2 | 1 | 2 | | LCHouse2 | 2 | 2 | | LCHouse3 | 4 | 1 | +------------+--------------+-------------+ Products 表: +------------+--------------+------------+----------+-----------+ | product_id | product_name | Width | Length | Height | +------------+--------------+------------+----------+-----------+ | 1 | LC-TV | 5 | 50 | 40 | | 2 | LC-KeyChain | 5 | 5 | 5 | | 3 | LC-Phone | 2 | 10 | 10 | | 4 | LC-T-Shirt | 4 | 10 | 20 | +------------+--------------+------------+----------+-----------+ 输出: +----------------+------------+ | warehouse_name| volume
| +----------------+------------+ | LCHouse1 | 12250 | | LCHouse2 | 20250 | | LCHouse3 | 800 | +----------------+------------+ 解释: Id为1的商品(LC-TV)的存货量为 5x50x40 = 10000 Id为2的商品(LC-KeyChain)的存货量为 5x5x5 = 125 Id为3的商品(LC-Phone)的存货量为 2x10x10 = 200 Id为4的商品(LC-T-Shirt)的存货量为 4x10x20 = 800 仓库LCHouse1: 1个单位的LC-TV + 10个单位的LC-KeyChain + 5个单位的LC-Phone. 总存货量为: 1*10000 + 10*125 + 5*200 = 12250 立方英尺 仓库LCHouse2: 2个单位的LC-TV + 2个单位的LC-KeyChain. 总存货量为: 2*10000 + 2*125 = 20250 立方英尺 仓库LCHouse3: 1个单位的LC-T-Shirt. 总存货量为: 1*800 = 800 立方英尺.
1.2 思路:
简单题,通过率高达80%,不用多说。
1.3 题解:
-- 优化一下Products 表
with tep as (
select product_id, product_name , Width*Length*Height wlh
from Products p
)
-- 简单的多表查询
select name warehouse_name, sum(wlh*units) volume
from Warehouse w
join tep
on w.product_id = tep.product_id
group by name
2. 力扣1715:苹果和橘子的个数
2.1 题目:
表: 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
2.2 思路:
注意到题目是左外连接就简单了。
2.3 题解:
-- 当chest_id为null时,c.apple_count和c.orange_count也就可能为null
with tep as (
select sum(b.apple_count) + ifNull(c.apple_count, 0) sum1,
sum(b.orange_count) + ifNull(c.orange_count, 0) sum2
-- 左外连接,即使不满足连接条件,也仅仅就是不用考虑计算小盒子的情况了
-- 但还要考虑到大盒子的情况
from Boxes b
left join Chests c
on b.chest_id = c.chest_id
group by box_id
)
select sum(sum1) apple_count,
sum(sum2) orange_count
from tep
3. 力扣1699:两人之间的通话次数
3.1 题目:
表: Calls
+-------------+---------+ | Column Name | Type | +-------------+---------+ | from_id | int | | to_id | int | | duration | int | +-------------+---------+ 该表没有主键(具有唯一值的列),它可能包含重复项。 该表包含 from_id 与 to_id 间的一次电话的时长。 from_id != to_id
编写解决方案,统计每一对用户 (person1, person2)
之间的通话次数和通话总时长,其中 person1 < person2
。
以 任意顺序 返回结果表。
返回结果格式如下示例所示。
示例 1:
输入: Calls 表: +---------+-------+----------+ | from_id | to_id | duration | +---------+-------+----------+ | 1 | 2 | 59 | | 2 | 1 | 11 | | 1 | 3 | 20 | | 3 | 4 | 100 | | 3 | 4 | 200 | | 3 | 4 | 200 | | 4 | 3 | 499 | +---------+-------+----------+ 输出: +---------+---------+------------+----------------+ | person1 | person2 | call_count | total_duration | +---------+---------+------------+----------------+ | 1 | 2 | 2 | 70 | | 1 | 3 | 1 | 20 | | 3 | 4 | 4 | 999 | +---------+---------+------------+----------------+ 解释: 用户 1 和 2 打过 2 次电话,总时长为 70 (59 + 11)。 用户 1 和 3 打过 1 次电话,总时长为 20。 用户 3 和 4 打过 4 次电话,总时长为 999 (100 + 200 + 200 + 499)。
3.2 思路:
题目很简单,只需要解决怎么处理一会to_id > from_id,一会又反过来的杂乱无章的表。
然后分组解决。
3.3 题解:
-- 优化一下Calls表,为了便于分组,始终保持person1 < person2
with tmp as (
select duration, if(to_id > from_id, from_id, to_id) person1,
if(to_id > from_id, to_id, from_id) person2
from Calls
)
-- 直接分组,然后计算个数和求和即可。
select person1,person2, count(*) call_count, sum(duration) total_duration
from tmp
group by person1, person2
4. 力扣1445:橘子和苹果
4.1 题目:
表: Sales
+---------------+---------+ | Column Name | Type | +---------------+---------+ | sale_date | date | | fruit | enum | | sold_num | int | +---------------+---------+ (sale_date, fruit) 是该表主键(具有唯一值的列的组合)。 该表包含了每一天中"苹果" 和 "桔子"的销售情况。
编写解决方案报告每一天 苹果 和 桔子 销售的数目的差异.
返回的结果表, 按照格式为 ('YYYY-MM-DD') 的 sale_date
排序.
返回结果表如下例所示:
示例 1:
输入:
Sales
表:
+------------+------------+-------------+
| sale_date | fruit | sold_num |
+------------+------------+-------------+
| 2020-05-01 | apples | 10 |
| 2020-05-01 | oranges | 8 |
| 2020-05-02 | apples | 15 |
| 2020-05-02 | oranges | 15 |
| 2020-05-03 | apples | 20 |
| 2020-05-03 | oranges | 0 |
| 2020-05-04 | apples | 15 |
| 2020-05-04 | oranges | 16 |
+------------+------------+-------------+
输出:
+------------+--------------+
| sale_date | diff |
+------------+--------------+
| 2020-05-01 | 2 |
| 2020-05-02 | 0 |
| 2020-05-03 | 20 |
| 2020-05-04 | -1 |
+------------+--------------+
解释:
在 2020-05-01, 卖了 10 个苹果 和 8 个桔子 (差异为 10 - 8 = 2).
在 2020-05-02, 卖了 15 个苹果 和 15 个桔子 (差异为 15 - 15 = 0).
在 2020-05-03, 卖了 20 个苹果 和 0 个桔子 (差异为 20 - 0 = 20).
在 2020-05-04, 卖了 15 个苹果 和 16 个桔子 (差异为 15 - 16 = -1).
4.2 思路:
不太会写一行写多个select语句的排版格式,希望有大佬教我啊佬。
4.3题解:
-- 以日期分组,计算出该天的苹果的数量和橘子的数量之差
select sale_date,
(select sum(sold_num) from Sales s1
where s1.sale_date = s.sale_date and s1.fruit = 'apples')
-
(select sum(sold_num) from Sales s2
where s2.sale_date = s.sale_date and s2.fruit = 'oranges')
diff
from Sales s
group by sale_date
5. 力扣1495:上月播放的儿童适宜电影
5.1 题目:
表: TVProgram
+---------------+---------+ | Column Name | Type | +---------------+---------+ | program_date | date | | content_id | int | | channel | varchar | +---------------+---------+ (program_date, content_id) 是该表的主键(具有唯一值的列的组合)。 该表包含电视上的节目信息。 content_id 是电视一些频道上的节目的 id。
表: Content
+------------------+---------+ | Column Name | Type | +------------------+---------+ | content_id | varchar | | title | varchar | | Kids_content | enum | | content_type | varchar | +------------------+---------+ content_id 是该表主键(具有唯一值的列)。 Kids_content 是枚举类型, 取值为('Y', 'N'), 其中: 'Y' 表示儿童适宜内容, 而'N'表示儿童不宜内容。 content_type 表示内容的类型, 比如电影, 电视剧等。
编写解决方案, 报告在 2020 年 6 月份播放的儿童适宜电影的去重电影名.
返回的结果表单 没有顺序要求 .
返回结果的格式如下例所示.
示例 1:
输入: TVProgram
表: +--------------------+--------------+-------------+ | program_date | content_id | channel | +--------------------+--------------+-------------+ | 2020-06-10 08:00 | 1 | LC-Channel | | 2020-05-11 12:00 | 2 | LC-Channel | | 2020-05-12 12:00 | 3 | LC-Channel | | 2020-05-13 14:00 | 4 | Disney Ch | | 2020-06-18 14:00 | 4 | Disney Ch | | 2020-07-15 16:00 | 5 | Disney Ch | +--------------------+--------------+-------------+Content
表: +------------+----------------+---------------+---------------+ | content_id | title | Kids_content | content_type | +------------+----------------+---------------+---------------+ | 1 | Leetcode Movie | N | Movies | | 2 | Alg. for Kids | Y | Series | | 3 | Database Sols | N | Series | | 4 | Aladdin | Y | Movies | | 5 | Cinderella | Y | Movies | +------------+----------------+---------------+---------------+输出:
+--------------+ | title | +--------------+ | Aladdin | +--------------+解释:
"Leetcode Movie" 是儿童不宜的电影. "Alg. for Kids" 不是电影. "Database Sols" 不是电影 "Aladin" 是电影, 儿童适宜, 并且在 2020 年 6 月份播放. "Cinderella" 不在 2020 年 6 月份播放.
5.2 思路:
一步一步翻译题目意思即可。多说一句,with as语句真好用。
5.3 题解:
-- 得到2020 年 6 月份播放的记录表
with temp as (
select *
from TVProgram
where substring(program_date, 1, 7) = '2020-06'
)
-- 记得distinct去重
select distinct title
from temp
join Content c
on temp.content_id = c.content_id
-- 过滤:适宜电影的去重电影名
where Kids_content = 'Y' and content_type = 'Movies'
6. 力扣1683:无效的推文
6.1 题目:
表:Tweets
+----------------+---------+ | Column Name | Type | +----------------+---------+ | tweet_id | int | | content | varchar | +----------------+---------+ 在 SQL 中,tweet_id 是这个表的主键。 这个表包含某社交媒体 App 中所有的推文。
查询所有无效推文的编号(ID)。当推文内容中的字符数严格大于 15
时,该推文是无效的。
以任意顺序返回结果表。
查询结果格式如下所示:
示例 1:
输入: Tweets 表: +----------+----------------------------------+ | tweet_id | content | +----------+----------------------------------+ | 1 | Vote for Biden | | 2 | Let us make America great again! | +----------+----------------------------------+ 输出: +----------+ | tweet_id | +----------+ | 2 | +----------+ 解释: 推文 1 的长度 length = 14。该推文是有效的。 推文 2 的长度 length = 32。该推文是无效的。
6.2 思路:
这题素在...
6.3 题解:
select tweet_id
from Tweets
where length(content) > 15