• LeetCode-高频 SQL 50 题:连接 篇


    目录

    1378. 使用唯一标识码替换员工ID

    题目描述:

    SQL语句:

    1068. 产品销售分析 I

    题目描述:

    SQL语句:

    1581. 进店却未进行过交易的顾客

    题目描述:

    SQL语句:

    197. 上升的温度

    题目描述:

    SQL语句:

    1661. 每台机器的进程平均运行时间

    题目描述:

    SQL语句:

    577. 员工奖金

    题目描述:

    SQL语句:

    1280. 学生们参加各科测试的次数

    题目描述:

    SQL语句:

    570. 至少有5名直接下属的经理

    题目描述:

    SQL语句:

    1934. 确认率

    SQL语句:


    1378. 使用唯一标识码替换员工ID

    题目描述:

    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:

    1. 输入:
    2. 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 。

    SQL语句:

    1. # Write your MySQL query statement below
    2. SELECT
    3. EmployeeUNI.unique_id, Employees.name
    4. FROM
    5. Employees
    6. LEFT JOIN
    7. EmployeeUNI
    8. ON
    9. Employees.id = EmployeeUNI.id
    10. ;

    1068. 产品销售分析 I

    题目描述:

    销售表 Sales

    +-------------+-------+
    | Column Name | Type  |
    +-------------+-------+
    | sale_id     | int   |
    | product_id  | int   |
    | year        | int   |
    | quantity    | int   |
    | price       | int   |
    +-------------+-------+
    (sale_id, year) 是销售表 Sales 的主键(具有唯一值的列的组合)。
    product_id 是关联到产品表 Product 的外键(reference 列)。
    该表的每一行显示 product_id 在某一年的销售情况。
    注意: price 表示每单位价格。
    

    产品表 Product

    +--------------+---------+
    | Column Name  | Type    |
    +--------------+---------+
    | product_id   | int     |
    | product_name | varchar |
    +--------------+---------+
    product_id 是表的主键(具有唯一值的列)。
    该表的每一行表示每种产品的产品名称。
    
    

    编写解决方案,以获取 Sales 表中所有 sale_id 对应的 product_name 以及该产品的所有 year 和 price 。

    返回结果表 无顺序要求 。

    结果格式示例如下。

    示例 1:

    1. 输入:
    2. Sales
    表: +---------+------------+------+----------+-------+ | sale_id | product_id | year | quantity | price | +---------+------------+------+----------+-------+ | 1 | 100 | 2008 | 10 | 5000 | | 2 | 100 | 2009 | 12 | 5000 | | 7 | 200 | 2011 | 15 | 9000 | +---------+------------+------+----------+-------+ Product 表: +------------+--------------+ | product_id | product_name | +------------+--------------+ | 100 | Nokia | | 200 | Apple | | 300 | Samsung | +------------+--------------+ 输出: +--------------+-------+-------+ | product_name | year | price | +--------------+-------+-------+ | Nokia | 2008 | 5000 | | Nokia | 2009 | 5000 | | Apple | 2011 | 9000 | +--------------+-------+-------+

    SQL语句:

    1. # Write your MySQL query statement below
    2. SELECT
    3. Product.product_name,
    4. Sales.year,
    5. Sales.price
    6. FROM
    7. Sales,
    8. Product
    9. WHERE
    10. Sales.product_id = Product. product_id
    11. ;

    1581. 进店却未进行过交易的顾客

    题目描述:

    表:Visits

    +-------------+---------+
    | Column Name | Type    |
    +-------------+---------+
    | visit_id    | int     |
    | customer_id | int     |
    +-------------+---------+
    visit_id 是该表中具有唯一值的列。
    该表包含有关光临过购物中心的顾客的信息。
    

    表:Transactions

    +----------------+---------+
    | Column Name    | Type    |
    +----------------+---------+
    | transaction_id | int     |
    | visit_id       | int     |
    | amount         | int     |
    +----------------+---------+
    transaction_id 是该表中具有唯一值的列。
    此表包含 visit_id 期间进行的交易的信息。
    
    

    有一些顾客可能光顾了购物中心但没有进行交易。请你编写一个解决方案,来查找这些顾客的 ID ,以及他们只光顾不交易的次数。

    返回以 任何顺序 排序的结果表。

    返回结果格式如下例所示。

    示例 1:

    1. 输入:
    2. Visits
    +----------+-------------+ | visit_id | customer_id | +----------+-------------+ | 1 | 23 | | 2 | 9 | | 4 | 30 | | 5 | 54 | | 6 | 96 | | 7 | 54 | | 8 | 54 | +----------+-------------+ Transactions +----------------+----------+--------+ | transaction_id | visit_id | amount | +----------------+----------+--------+ | 2 | 5 | 310 | | 3 | 5 | 300 | | 9 | 5 | 200 | | 12 | 1 | 910 | | 13 | 2 | 970 | +----------------+----------+--------+ 输出: +-------------+----------------+ | customer_id | count_no_trans | +-------------+----------------+ | 54 | 2 | | 30 | 1 | | 96 | 1 | +-------------+----------------+ 解释: ID = 23 的顾客曾经逛过一次购物中心,并在 ID = 12 的访问期间进行了一笔交易。 ID = 9 的顾客曾经逛过一次购物中心,并在 ID = 13 的访问期间进行了一笔交易。 ID = 30 的顾客曾经去过购物中心,并且没有进行任何交易。 ID = 54 的顾客三度造访了购物中心。在 2 次访问中,他们没有进行任何交易,在 1 次访问中,他们进行了 3 次交易。 ID = 96 的顾客曾经去过购物中心,并且没有进行任何交易。 如我们所见,ID 为 30 和 96 的顾客一次没有进行任何交易就去了购物中心。顾客 54 也两次访问了购物中心并且没有进行任何交易。

    SQL语句:

    1. # Write your MySQL query statement below
    2. SELECT
    3. customer_id,
    4. count(*) count_no_trans
    5. FROM
    6. Visits
    7. WHERE
    8. visit_id
    9. NOT IN
    10. (
    11. SELECT
    12. visit_id
    13. FROM
    14. Transactions
    15. )
    16. GROUP BY
    17. customer_id

    197. 上升的温度

    题目描述:

    表: Weather

    +---------------+---------+
    | Column Name   | Type    |
    +---------------+---------+
    | id            | int     |
    | recordDate    | date    |
    | temperature   | int     |
    +---------------+---------+
    id 是该表具有唯一值的列。
    该表包含特定日期的温度信息
    

    编写解决方案,找出与之前(昨天的)日期相比温度更高的所有日期的 id 。

    返回结果 无顺序要求 。

    结果格式如下例子所示

    示例 1:

    1. 输入:
    2. Weather 表:
    +----+------------+-------------+ | id | recordDate | Temperature | +----+------------+-------------+ | 1 | 2015-01-01 | 10 | | 2 | 2015-01-02 | 25 | | 3 | 2015-01-03 | 20 | | 4 | 2015-01-04 | 30 | +----+------------+-------------+ 输出: +----+ | id | +----+ | 2 | | 4 | +----+ 解释: 2015-01-02 的温度比前一天高(10 -> 25) 2015-01-04 的温度比前一天高(20 -> 30)

    SQL语句:

    1. # Write your MySQL query statement below
    2. SELECT
    3. w1.id
    4. FROM
    5. Weather w1,
    6. Weather w2
    7. WHERE
    8. w1.recordDate = ADDDATE(W2.recordDate, 1)
    9. AND w1.temperature > w2.temperature
    10. ;

    1661. 每台机器的进程平均运行时间

    题目描述:

    表: Activity

    +----------------+---------+
    | Column Name    | Type    |
    +----------------+---------+
    | machine_id     | int     |
    | process_id     | int     |
    | activity_type  | enum    |
    | timestamp      | float   |
    +----------------+---------+
    该表展示了一家工厂网站的用户活动。
    (machine_id, process_id, activity_type) 是当前表的主键(具有唯一值的列的组合)。
    machine_id 是一台机器的ID号。
    process_id 是运行在各机器上的进程ID号。
    activity_type 是枚举类型 ('start', 'end')。
    timestamp 是浮点类型,代表当前时间(以秒为单位)。
    'start' 代表该进程在这台机器上的开始运行时间戳 , 'end' 代表该进程在这台机器上的终止运行时间戳。
    同一台机器,同一个进程都有一对开始时间戳和结束时间戳,而且开始时间戳永远在结束时间戳前面。
    

    现在有一个工厂网站由几台机器运行,每台机器上运行着 相同数量的进程 。编写解决方案,计算每台机器各自完成一个进程任务的平均耗时。

    完成一个进程任务的时间指进程的'end' 时间戳 减去 'start' 时间戳。平均耗时通过计算每台机器上所有进程任务的总耗费时间除以机器上的总进程数量获得。

    结果表必须包含machine_id(机器ID) 和对应的 average time(平均耗时) 别名 processing_time,且四舍五入保留3位小数。

    以 任意顺序 返回表。

    具体参考例子如下。

    示例 1:

    输入:
    Activity table:
    +------------+------------+---------------+-----------+
    | machine_id | process_id | activity_type | timestamp |
    +------------+------------+---------------+-----------+
    | 0          | 0          | start         | 0.712     |
    | 0          | 0          | end           | 1.520     |
    | 0          | 1          | start         | 3.140     |
    | 0          | 1          | end           | 4.120     |
    | 1          | 0          | start         | 0.550     |
    | 1          | 0          | end           | 1.550     |
    | 1          | 1          | start         | 0.430     |
    | 1          | 1          | end           | 1.420     |
    | 2          | 0          | start         | 4.100     |
    | 2          | 0          | end           | 4.512     |
    | 2          | 1          | start         | 2.500     |
    | 2          | 1          | end           | 5.000     |
    +------------+------------+---------------+-----------+
    输出:
    +------------+-----------------+
    | machine_id | processing_time |
    +------------+-----------------+
    | 0          | 0.894           |
    | 1          | 0.995           |
    | 2          | 1.456           |
    +------------+-----------------+
    解释:
    一共有3台机器,每台机器运行着两个进程.
    机器 0 的平均耗时: ((1.520 - 0.712) + (4.120 - 3.140)) / 2 = 0.894
    机器 1 的平均耗时: ((1.550 - 0.550) + (1.420 - 0.430)) / 2 = 0.995
    机器 2 的平均耗时: ((4.512 - 4.100) + (5.000 - 2.500)) / 2 = 1.456

    SQL语句:

    1. # Write your MySQL query statement below
    2. SELECT
    3. a3.machine_id,
    4. ROUND(AVG(a3.process_time), 3) AS processing_time
    5. FROM (
    6. SELECT
    7. a1.machine_id,
    8. (a2.timestamp - a1.timestamp) AS process_time
    9. FROM
    10. Activity AS A1,
    11. Activity AS a2
    12. WHERE
    13. a1.machine_id = a2.machine_id
    14. AND a1.process_id = a2.process_id
    15. AND a1.activity_type = 'start'
    16. AND a2.activity_type = 'end'
    17. ) AS a3
    18. GROUP BY a3.machine_id

    577. 员工奖金

    题目描述:

    表:Employee 

    +-------------+---------+
    | Column Name | Type    |
    +-------------+---------+
    | empId       | int     |
    | name        | varchar |
    | supervisor  | int     |
    | salary      | int     |
    +-------------+---------+
    empId 是该表中具有唯一值的列。
    该表的每一行都表示员工的姓名和 id,以及他们的工资和经理的 id。
    

    表:Bonus

    +-------------+------+
    | Column Name | Type |
    +-------------+------+
    | empId       | int  |
    | bonus       | int  |
    +-------------+------+
    empId 是该表具有唯一值的列。
    empId 是 Employee 表中 empId 的外键(reference 列)。
    该表的每一行都包含一个员工的 id 和他们各自的奖金。
    
    

    编写解决方案,报告每个奖金 少于 1000 的员工的姓名和奖金数额。

    以 任意顺序 返回结果表。

    结果格式如下所示。

    示例 1:

    输入:
    Employee table:
    +-------+--------+------------+--------+
    | empId | name   | supervisor | salary |
    +-------+--------+------------+--------+
    | 3     | Brad   | null       | 4000   |
    | 1     | John   | 3          | 1000   |
    | 2     | Dan    | 3          | 2000   |
    | 4     | Thomas | 3          | 4000   |
    +-------+--------+------------+--------+
    Bonus table:
    +-------+-------+
    | empId | bonus |
    +-------+-------+
    | 2     | 500   |
    | 4     | 2000  |
    +-------+-------+
    输出:
    +------+-------+
    | name | bonus |
    +------+-------+
    | Brad | null  |
    | John | null  |
    | Dan  | 500   |
    +------+-------+

    SQL语句:

    1. # Write your MySQL query statement below
    2. SELECT
    3. et.name,
    4. bt.bonus
    5. FROM
    6. Employee AS et
    7. LEFT JOIN
    8. Bonus AS bt
    9. ON
    10. et.empId = bt.empId
    11. WHERE
    12. bt.bonus < 1000 OR
    13. bt.bonus is null
    14. ;

    1280. 学生们参加各科测试的次数

    题目描述:

    学生表: Students

    +---------------+---------+
    | Column Name   | Type    |
    +---------------+---------+
    | student_id    | int     |
    | student_name  | varchar |
    +---------------+---------+
    在 SQL 中,主键为 student_id(学生ID)。
    该表内的每一行都记录有学校一名学生的信息。
    

    科目表: Subjects

    +--------------+---------+
    | Column Name  | Type    |
    +--------------+---------+
    | subject_name | varchar |
    +--------------+---------+
    在 SQL 中,主键为 subject_name(科目名称)。
    每一行记录学校的一门科目名称。
    

    考试表: Examinations

    +--------------+---------+
    | Column Name  | Type    |
    +--------------+---------+
    | student_id   | int     |
    | subject_name | varchar |
    +--------------+---------+
    这个表可能包含重复数据(换句话说,在 SQL 中,这个表没有主键)。
    学生表里的一个学生修读科目表里的每一门科目。
    这张考试表的每一行记录就表示学生表里的某个学生参加了一次科目表里某门科目的测试。
    
    

    查询出每个学生参加每一门科目测试的次数,结果按 student_id 和 subject_name 排序。

    查询结构格式如下所示。

    示例 1:

    输入:
    Students table:
    +------------+--------------+
    | student_id | student_name |
    +------------+--------------+
    | 1          | Alice        |
    | 2          | Bob          |
    | 13         | John         |
    | 6          | Alex         |
    +------------+--------------+
    Subjects table:
    +--------------+
    | subject_name |
    +--------------+
    | Math         |
    | Physics      |
    | Programming  |
    +--------------+
    Examinations table:
    +------------+--------------+
    | student_id | subject_name |
    +------------+--------------+
    | 1          | Math         |
    | 1          | Physics      |
    | 1          | Programming  |
    | 2          | Programming  |
    | 1          | Physics      |
    | 1          | Math         |
    | 13         | Math         |
    | 13         | Programming  |
    | 13         | Physics      |
    | 2          | Math         |
    | 1          | Math         |
    +------------+--------------+
    输出:
    +------------+--------------+--------------+----------------+
    | student_id | student_name | subject_name | attended_exams |
    +------------+--------------+--------------+----------------+
    | 1          | Alice        | Math         | 3              |
    | 1          | Alice        | Physics      | 2              |
    | 1          | Alice        | Programming  | 1              |
    | 2          | Bob          | Math         | 1              |
    | 2          | Bob          | Physics      | 0              |
    | 2          | Bob          | Programming  | 1              |
    | 6          | Alex         | Math         | 0              |
    | 6          | Alex         | Physics      | 0              |
    | 6          | Alex         | Programming  | 0              |
    | 13         | John         | Math         | 1              |
    | 13         | John         | Physics      | 1              |
    | 13         | John         | Programming  | 1              |
    +------------+--------------+--------------+----------------+
    解释:
    结果表需包含所有学生和所有科目(即便测试次数为0):
    Alice 参加了 3 次数学测试, 2 次物理测试,以及 1 次编程测试;
    Bob 参加了 1 次数学测试, 1 次编程测试,没有参加物理测试;
    Alex 啥测试都没参加;
    John  参加了数学、物理、编程测试各 1 次。

    SQL语句:

    1. # Write your MySQL query statement below
    2. SELECT st.student_id,
    3. st.student_name,
    4. sb.subject_name,
    5. ifnull(attended_exams,
    6. 0) attended_exams
    7. FROM Students st
    8. CROSS JOIN Subjects sb
    9. LEFT JOIN
    10. (SELECT student_id,
    11. subject_name,
    12. count(*) attended_exams
    13. FROM Examinations
    14. GROUP BY student_id, subject_name) t
    15. ON st.student_id = t.student_id
    16. AND sb.subject_name = t.subject_name
    17. ORDER BY st.student_id, sb.subject_name;

    570. 至少有5名直接下属的经理

    题目描述:

    表: Employee

    +-------------+---------+
    | Column Name | Type    |
    +-------------+---------+
    | id          | int     |
    | name        | varchar |
    | department  | varchar |
    | managerId   | int     |
    +-------------+---------+
    在 SQL 中,id 是该表的主键列。
    该表的每一行都表示雇员的名字、他们的部门和他们的经理的id。
    如果managerId为空,则该员工没有经理。
    没有员工会成为自己的管理者。
    

    查询至少有5名直接下属的经理 

    以 任意顺序 返回结果表。

    查询结果格式如下所示。

    示例 1:

    输入: 
    Employee 表:
    +-----+-------+------------+-----------+
    | id  | name  | department | managerId |
    +-----+-------+------------+-----------+
    | 101 | John  | A          | None      |
    | 102 | Dan   | A          | 101       |
    | 103 | James | A          | 101       |
    | 104 | Amy   | A          | 101       |
    | 105 | Anne  | A          | 101       |
    | 106 | Ron   | B          | 101       |
    +-----+-------+------------+-----------+
    输出: 
    +------+
    | name |
    +------+
    | John |
    +------+

    SQL语句:

    1. # Write your MySQL query statement below
    2. select name from Employee e, (select count(*) cnt, managerId from Employee group by managerId) t where e.id = t.managerId and t.cnt >= 5

    1934. 确认率

    题目描述:

    表: Signups

    +----------------+----------+
    | Column Name    | Type     |
    +----------------+----------+
    | user_id        | int      |
    | time_stamp     | datetime |
    +----------------+----------+
    User_id是该表的主键。
    每一行都包含ID为user_id的用户的注册时间信息。
    

    表: Confirmations

    +----------------+----------+
    | Column Name    | Type     |
    +----------------+----------+
    | user_id        | int      |
    | time_stamp     | datetime |
    | action         | ENUM     |
    +----------------+----------+
    (user_id, time_stamp)是该表的主键。
    user_id是一个引用到注册表的外键。
    action是类型为('confirmed', 'timeout')的ENUM
    该表的每一行都表示ID为user_id的用户在time_stamp请求了一条确认消息,该确认消息要么被确认('confirmed'),要么被过期('timeout')。
    
    

    用户的 确认率 是 'confirmed' 消息的数量除以请求的确认消息的总数。没有请求任何确认消息的用户的确认率为 0 。确认率四舍五入到 小数点后两位 。

    编写一个SQL查询来查找每个用户的 确认率 。

    以 任意顺序 返回结果表。

    查询结果格式如下所示。

    示例1:

    输入:
    Signups 表:
    +---------+---------------------+
    | user_id | time_stamp          |
    +---------+---------------------+
    | 3       | 2020-03-21 10:16:13 |
    | 7       | 2020-01-04 13:57:59 |
    | 2       | 2020-07-29 23:09:44 |
    | 6       | 2020-12-09 10:39:37 |
    +---------+---------------------+
    Confirmations 表:
    +---------+---------------------+-----------+
    | user_id | time_stamp          | action    |
    +---------+---------------------+-----------+
    | 3       | 2021-01-06 03:30:46 | timeout   |
    | 3       | 2021-07-14 14:00:00 | timeout   |
    | 7       | 2021-06-12 11:57:29 | confirmed |
    | 7       | 2021-06-13 12:58:28 | confirmed |
    | 7       | 2021-06-14 13:59:27 | confirmed |
    | 2       | 2021-01-22 00:00:00 | confirmed |
    | 2       | 2021-02-28 23:59:59 | timeout   |
    +---------+---------------------+-----------+
    输出: 
    +---------+-------------------+
    | user_id | confirmation_rate |
    +---------+-------------------+
    | 6       | 0.00              |
    | 3       | 0.00              |
    | 7       | 1.00              |
    | 2       | 0.50              |
    +---------+-------------------+
    解释:
    用户 6 没有请求任何确认消息。确认率为 0。
    用户 3 进行了 2 次请求,都超时了。确认率为 0。
    用户 7 提出了 3 个请求,所有请求都得到了确认。确认率为 1。
    用户 2 做了 2 个请求,其中一个被确认,另一个超时。确认率为 1 / 2 = 0.5。

    SQL语句:

    1. # Write your MySQL query statement below
    2. SELECT
    3. user_id,
    4. round(avg(if(action = 'confirmed', 1, 0)), 2) confirmation_rate
    5. FROM
    6. (
    7. SELECT
    8. s.user_id,
    9. c.action
    10. FROM
    11. Signups s
    12. LEFT JOIN Confirmations c ON s.user_id = c.user_id
    13. ) t
    14. GROUP BY
    15. user_id
  • 相关阅读:
    JSP注释方式演示 讲解显式与隐式注释
    第12章 PyTorch图像分割代码框架-1
    【华为OD题库-008】座位调整-Java
    3. Apache HBase 为什么快?
    circt firtool man page
    【Python编程】四、python字符串
    触摸屏实验(触摸屏介绍+硬件设计+软件设计。注:软件部分代码过长,理解即可)
    发布有关陕西省工程师职称评审申报细节注意事项
    ubuntu 小技巧
    【微信小程序】实现页面跳转功能
  • 原文地址:https://blog.csdn.net/Cosmoshhhyyy/article/details/133888907