1821_Easy_发票中的产品金额
Product 表:
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| product_id | int |
| name | varchar |
+-------------+---------+
product_id 是这张表的主键
表中含有产品 id 、产品名称。产品名称都是小写的英文字母,产品名称都是唯一的
Invoice 表:
+-------------+------+
| Column Name | Type |
+-------------+------+
| invoice_id | int |
| product_id | int |
| rest | int |
| paid | int |
| canceled | int |
| refunded | int |
+-------------+------+
invoice_id 发票 id ,是这张表的主键
product_id 产品 id
rest 应缴款项
paid 已支付金额
canceled 已取消金额
refunded 已退款金额
要求写一个SQL查询,返回全部发票中每个产品的产品名称、总应缴款项、总已支付金额、总已取消金额、总已退款金额
查询结果按 product_name排序
示例:
Product 表:
+------------+-------+
| product_id | name |
+------------+-------+
| 0 | ham |
| 1 | bacon |
+------------+-------+
Invoice table:
+------------+------------+------+------+----------+----------+
| invoice_id | product_id | rest | paid | canceled | refunded |
+------------+------------+------+------+----------+----------+
| 23 | 0 | 2 | 0 | 5 | 0 |
| 12 | 0 | 0 | 4 | 0 | 3 |
| 1 | 1 | 1 | 1 | 0 | 1 |
| 2 | 1 | 1 | 0 | 1 | 1 |
| 3 | 1 | 0 | 1 | 1 | 1 |
| 4 | 1 | 1 | 1 | 1 | 0 |
+------------+------------+------+------+----------+----------+
Result 表:
+-------+------+------+----------+----------+
| name | rest | paid | canceled | refunded |
+-------+------+------+----------+----------+
| bacon | 3 | 3 | 3 | 3 |
| ham | 2 | 4 | 5 | 3 |
+-------+------+------+----------+----------+
- bacon 的总应缴款项为 1 + 1 + 0 + 1 = 3
- bacon 的总已支付金额为 1 + 0 + 1 + 1 = 3
- bacon 的总已取消金额为 0 + 1 + 1 + 1 = 3
- bacon 的总已退款金额为 1 + 1 + 1 + 0 = 3
- ham 的总应缴款项为 2 + 0 = 2
- ham 的总已支付金额为 0 + 4 = 4
- ham 的总已取消金额为 5 + 0 = 5
- ham 的总已退款金额为 0 + 3 = 3
建表+导数
create table 1821_Product(product_id int, name string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
load data inpath "/leetcode/1812_Product" overwrite into table 1821_Product;
select * from 1821_Product
create table 1821_Invoice(invoice_id int, product_id int, rest int, paid int, canceled int, refunded int) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
load data inpath "/leetcode/1812_Invoice" overwrite into table 1821_Invoice;
select * from 1821_Invoice
知识点:
select
p.name, sum(i.rest) rest, sum(i.paid) paid, sum(i.canceled) canceled, sum(i.refunded) refunded
from 1821_Product p
left join 1821_Invoice i
on p.product_id=i.product_id
group by p.name
执行结果;
1827_Easy_无效的推文
表:Tweets
+----------------+---------+
| Column Name | Type |
+----------------+---------+
| tweet_id | int |
| content | varchar |
+----------------+---------+
tweet_id 是这个表的主键。
这个表包含某社交媒体 App 中所有的推文。
写一条SQL 语句,查询所有无效推文的编号(ID)。当推文内容中的字符数严格大于 15 时,该推文是无效的。
以任意顺序返回结果表。
查询结果格式如下示例所示:
Tweets 表:
+----------+----------------------------------+
| tweet_id | content |
+----------+----------------------------------+
| 1 | Vote for Biden |
| 2 | Let us make America great again! |
+----------+----------------------------------+
结果表:
+----------+
| tweet_id |
+----------+
| 2 |
+----------+
推文 1 的长度 length = 14。该推文是有效的。
推文 2 的长度 length = 32。该推文是无效的。
建表+导数
create table 1827_Tweets(tweet_id int, content string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
load data inpath "/leetcode/1827_Tweets" overwrite into table 1827_Tweets;
select * from 1827_Tweets
知识点:length
select
tweet_id
from 1827_Tweets
where length(content) > 15
1837_Easy_每天的领导和合伙人
表:DailySales
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| date_id | date |
| make_name | varchar |
| lead_id | int |
| partner_id | int |
+-------------+---------+
该表没有主键。
该表包含日期、产品的名称,以及售给的领导和合伙人的编号。
名称只包含小写英文字母。
写一条 SQL 语句,使得对于每一个date_id和make_name,返回不同的lead_id以及不同的partner_id的数量。
按任意顺序返回结果表。
查询结果格式如下示例所示:
DailySales 表:
+-----------+-----------+---------+------------+
| date_id | make_name | lead_id | partner_id |
+-----------+-----------+---------+------------+
| 2020-12-8 | toyota | 0 | 1 |
| 2020-12-8 | toyota | 1 | 0 |
| 2020-12-8 | toyota | 1 | 2 |
| 2020-12-7 | toyota | 0 | 2 |
| 2020-12-7 | toyota | 0 | 1 |
| 2020-12-8 | honda | 1 | 2 |
| 2020-12-8 | honda | 2 | 1 |
| 2020-12-7 | honda | 0 | 1 |
| 2020-12-7 | honda | 1 | 2 |
| 2020-12-7 | honda | 2 | 1 |
+-----------+-----------+---------+------------+
结果表:
+-----------+-----------+--------------+-----------------+
| date_id | make_name | unique_leads | unique_partners |
+-----------+-----------+--------------+-----------------+
| 2020-12-8 | toyota | 2 | 3 |
| 2020-12-7 | toyota | 1 | 2 |
| 2020-12-8 | honda | 2 | 2 |
| 2020-12-7 | honda | 3 | 2 |
+-----------+-----------+--------------+-----------------+
在 2020-12-8,丰田(toyota)有领导者 = [0, 1] 和合伙人 = [0, 1, 2] ,同时本田(honda)有领导者 = [1, 2] 和合伙人 = [1, 2]。
在 2020-12-7,丰田(toyota)有领导者 = [0] 和合伙人 = [1, 2] ,同时本田(honda)有领导者 = [0, 1, 2] 和合伙人 = [1, 2]。
建表+导数
drop table 1837_DailySales
create table 1837_DailySales(date_id date, make_name string, lead_id int, partner_id int) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
load data inpath "/leetcode/1837_DailySales" overwrite into table 1837_DailySales;
select * from 1837_DailySales
知识点:count(distinct(xxx))
select
date_id, make_name, count(distinct(lead_id)) unique_leads , count(distinct(partner_id)) unique_partners
from 1837_DailySales
group by date_id, make_name
执行结果:
1842_Medium_两人之间的通话次数
表:Calls
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| from_id | int |
| to_id | int |
| duration | int |
+-------------+---------+
该表没有主键,可能存在重复项。
该表包含 from_id 与 to_id 间的一次电话的时长。
from_id != to_id
编写 SQL 语句,查询每一对用户(person1, person2)之间的通话次数和通话总时长,其中person1 < person2。
以任意顺序返回结果表。
查询结果格式如下示例所示:
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)。
建表+导数
create table 1842_Calls(from_id int, to_id int, duration int) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
load data inpath "/leetcode/1842_Calls" overwrite into table 1842_Calls;
select * from 1842_Calls
知识点:case进行行数据转换
select
t.small_id person1, big_id person2, count(1) call_count, sum(t.duration) total_duration
from
(
select
case when from_id>to_id then to_id else from_id end small_id,
case when from_id<to_id then to_id else from_id end big_id,
duration
from 1842_Calls
) t
group by t.small_id, big_id
执行结果:
1852_Medium_访问日期之间最大的空档期
表:UserVisits
+-------------+------+
| Column Name | Type |
+-------------+------+
| user_id | int |
| visit_date | date |
+-------------+------+
该表没有主键。
该表包含用户访问某特定零售商的日期日志。
假设今天的日期是'2021-1-1'。
编写 SQL 语句,对于每个user_id,求出每次访问及其下一个访问(若该次访问是最后一次,则为今天)之间最大的空档期天数window。
返回结果表,按用户编号user_id排序。
查询格式如下示例所示:
UserVisits 表:
+---------+------------+
| user_id | visit_date |
+---------+------------+
| 1 | 2020-11-28 |
| 1 | 2020-10-20 |
| 1 | 2020-12-3 |
| 2 | 2020-10-5 |
| 2 | 2020-12-9 |
| 3 | 2020-11-11 |
+---------+------------+
结果表:
+---------+---------------+
| user_id | biggest_window|
+---------+---------------+
| 1 | 39 |
| 2 | 65 |
| 3 | 51 |
+---------+---------------+
对于第一个用户,问题中的空档期在以下日期之间:
- 2020-10-20 至 2020-11-28 ,共计 39 天。
- 2020-11-28 至 2020-12-3 ,共计 5 天。
- 2020-12-3 至 2021-1-1 ,共计 29 天。
由此得出,最大的空档期为 39 天。
对于第二个用户,问题中的空档期在以下日期之间:
- 2020-10-5 至 2020-12-9 ,共计 65 天。
- 2020-12-9 至 2021-1-1 ,共计 23 天。
由此得出,最大的空档期为 65 天。
对于第三个用户,问题中的唯一空档期在 2020-11-11 至 2021-1-1 之间,共计 51 天。
建表+导数
create table 1852_UserVisits(user_id int, visit_date date) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
load data inpath "/leetcode/1852_UserVisits" overwrite into table 1852_UserVisits;
select * from 1852_UserVisits
知识点:lead开窗,向窗口后取第n条
select
tt.user_id, tt.date_diff biggest_window
from
(
select
t.user_id,
date_diff,
rank() over(partition by t.user_id order by date_diff desc) rk
from
(
select
user_id,
datediff(
lead(visit_date,1,'2021-1-1') over(partition by user_id order by visit_date),
visit_date
) date_diff
from 1852_UserVisits
) t
) tt
where tt.rk=1
执行结果:
1862_Medium_苹果和橘子的个数
表: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 语句,查询每个大箱子中苹果和橘子的个数。如果大箱子中包含小盒子,还应当包含小盒子中苹果和橘子的个数。
以任意顺序返回结果表。
查询结果的格式如下示例所示:
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
建表+导数
create table 1862_Boxes(box_id int, chest_id int, apple_count int, orange_count int) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
load data inpath "/leetcode/1862_Boxes" overwrite into table 1862_Boxes;
select * from 1862_Boxes
create table 1862_Chests(chest_id int, apple_count int, orange_count int) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
load data inpath "/leetcode/1862_Chests" overwrite into table 1862_Chests;
select * from 1862_Chests
知识点:左连接+聚合
select
b.box_id, b.apple_count+coalesce(c.apple_count,0) apple_count,
b.orange_count+coalesce(c.orange_count,0) orange_count
from 1862_Boxes b
left join 1862_Chests c
on b.chest_id=c.chest_id
执行结果:
1877_Easy_求关注者的数量
表:Followers
+-------------+------+
| Column Name | Type |
+-------------+------+
| user_id | int |
| follower_id | int |
+-------------+------+
(user_id, follower_id) 是这个表的主键。
该表包含一个关注关系中关注者和用户的编号,其中关注者关注用户。
写出 SQL 语句,对于每一个用户,返回该用户的关注者数量。
按user_id的顺序返回结果表。
查询结果的格式如下示例所示:
Followers 表:
+---------+-------------+
| user_id | follower_id |
+---------+-------------+
| 0 | 1 |
| 1 | 0 |
| 2 | 0 |
| 2 | 1 |
+---------+-------------+
结果表:
+---------+----------------+
| user_id | followers_count|
+---------+----------------+
| 0 | 1 |
| 1 | 1 |
| 2 | 2 |
+---------+----------------+
0 的关注者有 {1}
1 的关注者有 {0}
2 的关注者有 {0,1}
建表+导数
create table 1877_Followers(user_id int, follower_id int) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
load data inpath "/leetcode/1877_Followers" overwrite into table 1877_Followers;
select * from 1877_Followers
知识点:group by 搞定
select
user_id, count(1) followers_count
from 1877_Followers
group by user_id
执行结果:
1908_Easy_可回收且低脂的产品
表:Products
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| product_id | int |
| low_fats | enum |
| recyclable | enum |
+-------------+---------+
product_id 是这个表的主键。
low_fats 是枚举类型,取值为以下两种 ('Y', 'N'),其中 'Y' 表示该产品是低脂产品,'N' 表示不是低脂产品。
recyclable 是枚举类型,取值为以下两种 ('Y', 'N'),其中 'Y' 表示该产品可回收,而 'N' 表示不可回收。
写出 SQL 语句,查找既是低脂又是可回收的产品编号。
返回结果 无顺序要求 。
查询结果格式如下例所示:
Products 表:
+-------------+----------+------------+
| product_id | low_fats | recyclable |
+-------------+----------+------------+
| 0 | Y | N |
| 1 | Y | Y |
| 2 | N | Y |
| 3 | Y | Y |
| 4 | N | N |
+-------------+----------+------------+
Result 表:
+-------------+
| product_id |
+-------------+
| 1 |
| 3 |
+-------------+
只有产品 id 为 1 和 3 的产品,既是低脂又是可回收的产品。
建表+导数
create table 1908_Products(product_id int, low_fats string, recyclable string) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
load data inpath "/leetcode/1908_Products" overwrite into table 1908_Products;
select * from 1908_Products
知识点:where 条件过滤
select product_id
from 1908_Products
where low_fats='Y' and recyclable='Y'
执行结果:
1926_Easy_每家商店的产品价格
表:Products
+-------------+---------+
| Column Name | Type |
+-------------+---------+
| product_id | int |
| store | enum |
| price | int |
+-------------+---------+
(product_id,store) 是这个表的主键。
store 字段是枚举类型,它的取值为以下三种 ('store1', 'store2', 'store3') 。
price 是该商品在这家商店中的价格。
写出一个 SQL 查询语句,查找每种产品在各个商店中的价格。
可以以 任何顺序 输出结果。
查询结果格式如下例所示:
Products 表:
+-------------+--------+-------+
| product_id | store | price |
+-------------+--------+-------+
| 0 | store1 | 95 |
| 0 | store3 | 105 |
| 0 | store2 | 100 |
| 1 | store1 | 70 |
| 1 | store3 | 80 |
+-------------+--------+-------+
Result 表:
+-------------+--------+--------+--------+
| product_id | store1 | store2 | store3 |
+-------------+--------+--------+--------+
| 0 | 95 | 100 | 105 |
| 1 | 70 | null | 80 |
+-------------+--------+--------+--------+
产品 0 的价格在商店 1 为 95 ,商店 2 为 100 ,商店 3 为 105 。
产品 1 的价格在商店 1 为 70 ,商店 3 的产品 1 价格为 80 ,但在商店 2 中没有销售。
建表+导数
create table 1926_Products(product_id int, store string, price int) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t';
load data inpath "/leetcode/1962_Products" overwrite into table 1926_Products;
select * from 1926_Products
知识点:grpup by sum
select
product_id,
sum(case when store='store1' then price end) store1,
sum(case when store='store2' then price end) store2,
sum(case when store='store3' then price end) store3
from 1926_Products
group by product_id
执行结果: