【力扣 | SQL题 | 每日四题】力扣1440, 1378, 1421, 1393, 1407

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
相关推荐
懒惰才能让科技进步11 分钟前
从零学习大模型(十二)-----基于梯度的重要性剪枝(Gradient-based Pruning)
人工智能·深度学习·学习·算法·chatgpt·transformer·剪枝
Ni-Guvara25 分钟前
函数对象笔记
c++·算法
测试199826 分钟前
2024软件测试面试热点问题
自动化测试·软件测试·python·测试工具·面试·职场和发展·压力测试
泉崎1 小时前
11.7比赛总结
数据结构·算法
你好helloworld1 小时前
滑动窗口最大值
数据结构·算法·leetcode
AI街潜水的八角1 小时前
基于C++的决策树C4.5机器学习算法(不调包)
c++·算法·决策树·机器学习
白榆maple2 小时前
(蓝桥杯C/C++)——基础算法(下)
算法
JSU_曾是此间年少2 小时前
数据结构——线性表与链表
数据结构·c++·算法
sjsjs112 小时前
【数据结构-合法括号字符串】【hard】【拼多多面试题】力扣32. 最长有效括号
数据结构·leetcode
此生只爱蛋3 小时前
【手撕排序2】快速排序
c语言·c++·算法·排序算法