1. 力扣1440:计算布尔值表达式的值
1.1 题目:
表 Variables
:
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| name | varchar |
| value | int |
+---------------+---------+
在 SQL 中,name 是该表主键.
该表包含了存储的变量及其对应的值.
表 Expressions
:
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| left_operand | varchar |
| operator | enum |
| right_operand | varchar |
+---------------+---------+
在 SQL 中,(left_operand, operator, right_operand) 是该表主键.
该表包含了需要计算的布尔表达式.
operator 是枚举类型, 取值于('<', '>', '=')
left_operand 和 right_operand 的值保证存在于 Variables 表单中.
计算表 Expressions
中的布尔表达式。
返回的结果表 无顺序要求 。
结果格式如下例所示。
示例 1:
输入:
Variables 表:
+------+-------+
| name | value |
+------+-------+
| x | 66 |
| y | 77 |
+------+-------+
Expressions 表:
+--------------+----------+---------------+
| left_operand | operator | right_operand |
+--------------+----------+---------------+
| x | > | y |
| x | < | y |
| x | = | y |
| y | > | x |
| y | < | x |
| x | = | x |
+--------------+----------+---------------+
输出:
+--------------+----------+---------------+-------+
| left_operand | operator | right_operand | value |
+--------------+----------+---------------+-------+
| x | > | y | false |
| x | < | y | true |
| x | = | y | false |
| y | > | x | true |
| y | < | x | false |
| x | = | x | true |
+--------------+----------+---------------+-------+
解释:
如上所示, 你需要通过使用 Variables 表来找到 Expressions 表中的每一个布尔表达式的值.
1.2 思路:
使用到了case when语句和if函数。
1.3 题解:
sql
select left_operand, operator, right_operand,
-- 三种情况:使用case when then 语句
-- 再使用两个子查询找到两边的操作数,然后使用if函数判断value
case operator when '<' then if((select value from Variables where name = left_operand) < (select value from Variables where name = right_operand), 'true', 'false')
when '>' then if((select value from Variables where name = left_operand) > (select value from Variables where name = right_operand), 'true', 'false')
else if((select value from Variables where name = left_operand) = (select value from Variables where name = right_operand), 'true', 'false')
end as value
from Expressions e
2. 力扣1378:使用唯一标识码替换员工ID
2.1 题目:
Employees
表:
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| name | varchar |
+---------------+---------+
在 SQL 中,id 是这张表的主键。
这张表的每一行分别代表了某公司其中一位员工的名字和 ID 。
EmployeeUNI
表:
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| unique_id | int |
+---------------+---------+
在 SQL 中,(id, unique_id) 是这张表的主键。
这张表的每一行包含了该公司某位员工的 ID 和他的唯一标识码(unique ID)。
展示每位用户的唯一标识码(unique ID );如果某位员工没有唯一标识码,使用 null 填充即可。
你可以以任意 顺序返回结果表。
返回结果的格式如下例所示。
示例 1:
输入:
Employees 表:
+----+----------+
| id | name |
+----+----------+
| 1 | Alice |
| 7 | Bob |
| 11 | Meir |
| 90 | Winston |
| 3 | Jonathan |
+----+----------+
EmployeeUNI 表:
+----+-----------+
| id | unique_id |
+----+-----------+
| 3 | 1 |
| 11 | 2 |
| 90 | 3 |
+----+-----------+
输出:
+-----------+----------+
| unique_id | name |
+-----------+----------+
| null | Alice |
| null | Bob |
| 2 | Meir |
| 3 | Winston |
| 1 | Jonathan |
+-----------+----------+
解释:
Alice and Bob 没有唯一标识码, 因此我们使用 null 替代。
Meir 的唯一标识码是 2 。
Winston 的唯一标识码是 3 。
Jonathan 唯一标识码是 1 。
2.2 思路:
简单的左外连接,使用到if函数考虑到左外连接unique_id为null的情况.
2.3 题解:
sql
select if(unique_id is null, null, unique_id) unique_id , name
from Employees e1
left join EmployeeUNI e2
on e1.id = e2.id
3. 力扣1421:净现值查找
3.1 题目:
表: NPV
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| year | int |
| npv | int |
+---------------+---------+
(id, year) 是该表主键(具有唯一值的列的组合).
该表有每一笔存货的年份, id 和对应净现值的信息.
表: Queries
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| year | int |
+---------------+---------+
(id, year) 是该表主键(具有唯一值的列的组合).
该表有每一次查询所对应存货的 id 和年份的信息.
编写解决方案,找到 Queries 表中每一次查询的净现值。
结果表 没有顺序要求。
查询结果的格式如下所示:
示例 1:
输入:
NPV 表:
+------+--------+--------+
| id | year | npv |
+------+--------+--------+
| 1 | 2018 | 100 |
| 7 | 2020 | 30 |
| 13 | 2019 | 40 |
| 1 | 2019 | 113 |
| 2 | 2008 | 121 |
| 3 | 2009 | 12 |
| 11 | 2020 | 99 |
| 7 | 2019 | 0 |
+------+--------+--------+
Queries 表:
+------+--------+
| id | year |
+------+--------+
| 1 | 2019 |
| 2 | 2008 |
| 3 | 2009 |
| 7 | 2018 |
| 7 | 2019 |
| 7 | 2020 |
| 13 | 2019 |
+------+--------+
输出:
+------+--------+--------+
| id | year | npv |
+------+--------+--------+
| 1 | 2019 | 113 |
| 2 | 2008 | 121 |
| 3 | 2009 | 12 |
| 7 | 2018 | 0 |
| 7 | 2019 | 0 |
| 7 | 2020 | 30 |
| 13 | 2019 | 40 |
+------+--------+--------+
解释:
(7, 2018)的净现值不在 NPV 表中, 我们把它看作是 0.
所有其它查询的净现值都能在 NPV 表中找到.
3.2 思路:
看注释。
3.3 题解:
sql
-- 遍历Queries表中的每一条记录
-- 从NPV表中找到对应的净现值
-- ifNull函数当没查询到净现值时,则用0替代
select id, year,ifNull(
(select npv
from NPV n
where n.id = q.id and n.year = q.year), 0
) npv
from Queries q
4. 力扣1393:股票的资本损益
4.1 题目:
Stocks
表:
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| stock_name | varchar |
| operation | enum |
| operation_day | int |
| price | int |
+---------------+---------+
(stock_name, operation_day) 是这张表的主键(具有唯一值的列的组合)
operation 列使用的是一种枚举类型,包括:('Sell','Buy')
此表的每一行代表了名为 stock_name 的某支股票在 operation_day 这一天的操作价格。
此表可以保证,股票的每个“卖出”操作在前一天都有相应的“买入”操作。并且,股票的每个“买入”操作在即将到来的一天都有相应的“卖出”操作。
编写解决方案报告每只股票的 资本损益。
股票的 资本利得/损失是指一次或多次买卖该股票后的总收益或损失。
以 任意顺序 返回结果表。
结果格式如下所示。
示例 1:
输入:
Stocks 表:
+---------------+-----------+---------------+--------+
| stock_name | operation | operation_day | price |
+---------------+-----------+---------------+--------+
| Leetcode | Buy | 1 | 1000 |
| Corona Masks | Buy | 2 | 10 |
| Leetcode | Sell | 5 | 9000 |
| Handbags | Buy | 17 | 30000 |
| Corona Masks | Sell | 3 | 1010 |
| Corona Masks | Buy | 4 | 1000 |
| Corona Masks | Sell | 5 | 500 |
| Corona Masks | Buy | 6 | 1000 |
| Handbags | Sell | 29 | 7000 |
| Corona Masks | Sell | 10 | 10000 |
+---------------+-----------+---------------+--------+
输出:
+---------------+-------------------+
| stock_name | capital_gain_loss |
+---------------+-------------------+
| Corona Masks | 9500 |
| Leetcode | 8000 |
| Handbags | -23000 |
+---------------+-------------------+
解释:
Leetcode 股票在第一天以1000美元的价格买入,在第五天以9000美元的价格卖出。资本收益=9000-1000=8000美元。
Handbags 股票在第17天以30000美元的价格买入,在第29天以7000美元的价格卖出。资本损失=7000-30000=-23000美元。
Corona Masks 股票在第1天以10美元的价格买入,在第3天以1010美元的价格卖出。在第4天以1000美元的价格再次购买,在第5天以500美元的价格出售。最后,它在第6天以1000美元的价格被买走,在第10天以10000美元的价格被卖掉。资本损益是每次(’Buy'->'Sell')操作资本收益或损失的和=(1010-10)+(500-1000)+(10000-1000)=1000-500+9000=9500美元。
4.2 思路:
4.3 题解:
sql
-- 以stock_name分组。计算出其卖出的股票减去买的股票
-- where operation = 'Sell' and s2.stock_name = s.stock_name
-- 找到外面一条记录的卖出股票的收益
-- where operation = 'Buy' and s1.stock_name = s.stock_name
-- 找到外面一条记录的买进的成本
select stock_name, ((
select sum(price)
from Stocks s2
where operation = 'Sell' and s2.stock_name = s.stock_name
) - (
select sum(price)
from Stocks s1
where operation = 'Buy' and s1.stock_name = s.stock_name
)) capital_gain_loss
from Stocks s
group by stock_name
5. 力扣1407:排名靠前的旅行者
5.1 题目:
表:Users
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| name | varchar |
+---------------+---------+
id 是该表中具有唯一值的列。
name 是用户名字。
表:Rides
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| id | int |
| user_id | int |
| distance | int |
+---------------+---------+
id 是该表中具有唯一值的列。
user_id 是本次行程的用户的 id, 而该用户此次行程距离为 distance 。
编写解决方案,报告每个用户的旅行距离。
返回的结果表单,以 travelled_distance
降序排列 ,如果有两个或者更多的用户旅行了相同的距离, 那么再以 name
升序排列 。
返回结果格式如下例所示。
示例 1:
输入:
Users 表:
+------+-----------+
| id | name |
+------+-----------+
| 1 | Alice |
| 2 | Bob |
| 3 | Alex |
| 4 | Donald |
| 7 | Lee |
| 13 | Jonathan |
| 19 | Elvis |
+------+-----------+
Rides 表:
+------+----------+----------+
| id | user_id | distance |
+------+----------+----------+
| 1 | 1 | 120 |
| 2 | 2 | 317 |
| 3 | 3 | 222 |
| 4 | 7 | 100 |
| 5 | 13 | 312 |
| 6 | 19 | 50 |
| 7 | 7 | 120 |
| 8 | 19 | 400 |
| 9 | 7 | 230 |
+------+----------+----------+
输出:
+----------+--------------------+
| name | travelled_distance |
+----------+--------------------+
| Elvis | 450 |
| Lee | 450 |
| Bob | 317 |
| Jonathan | 312 |
| Alex | 222 |
| Alice | 120 |
| Donald | 0 |
+----------+--------------------+
解释:
Elvis 和 Lee 旅行了 450 英里,Elvis 是排名靠前的旅行者,因为他的名字在字母表上的排序比 Lee 更小。
Bob, Jonathan, Alex 和 Alice 只有一次行程,我们只按此次行程的全部距离对他们排序。
Donald 没有任何行程, 他的旅行距离为 0。
5.2 思路:
看注释。
5.3 题解:
sql
-- 创建temp表,得到我们需要的表
-- 分组,求得每个用户的总行程
with temp as (
select sum(distance) sum_distance, user_id, name
from Users u
left join Rides r
on u.id = r.user_id
group by user_id
)
select name, ifNull(sum_distance, 0) travelled_distance
from temp
order by travelled_distance desc, name