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 题解:
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 题解:
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 题解:
-- 遍历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 题解:
-- 以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 题解:
-- 创建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