高频SQL50题(基础版)二

简介: 高频SQL50题(基础版)二

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如下:

select t2.unique_id,t1.name from Employees as t1
left join EmployeeUNI  as t2 
on t1.id  = t2.id;

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:

输入:
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如下:

select t1.year,t1.price,t2.product_name 
from Sales as t1 
left join Product as t2
on t1.product_id = t2.product_id 

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:

输入:
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如下:

select customer_id ,count(visit_id ) as count_no_trans
from Visits
where visit_id not in(select distinct visit_id from Transactions)
group by customer_id ;

197.上升的温度(简单)

表: Weather

+---------------+---------+

| Column Name   | Type    |

+---------------+---------+

| id            | int     |

| recordDate    | date    |

| temperature   | int     |

+---------------+---------+

id 是该表具有唯一值的列。

没有具有相同 recordDate 的不同行。

该表包含特定日期的温度信息

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


返回结果 无顺序要求 。


结果格式如下例子所示。


示例 1:


输入:

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如下:

#本题考查自连接和日期函数的应用#
select a.id 
from Weather as a, Weather as b 
where  datediff(a.recordDate,b.recordDate) = 1 
and a.Temperature > b.Temperature ;

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如下:

#使用连接语法,将Activity表分开组后做汇总运算
select a.machine_id ,round(avg(b.timestamp - a.timestamp),3) as processing_time 
from (select * from Activity where activity_type = 'start') as a
left join (select * from Activity where activity_type = 'end') as b
on a.machine_id  = b.machine_id and a.process_id = b.process_id 
group by 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如下:

select t1.name,t2.bonus 
from Employee as t1 
left join Bonus as t2 on t1.empId = t2.empId 
where t2.bonus is null or t2.bonus <1000;

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如下:

select t1.student_id ,t1.student_name ,t2.subject_name ,count(t3.subject_name) as attended_exams 
from Students as t1
join Subjects as t2
left join Examinations as t3
on t1.student_id = t3.student_id 
and t2.subject_name = t3.subject_name 
group by t1.student_id ,t2.subject_name  
order by t1.student_id ,t2.subject_name

570.至少有5名直接下属的经理(中等)

表: Employee

+-------------+---------+

| Column Name | Type    |

+-------------+---------+

| id          | int     |

| name        | varchar |

| department  | varchar |

| managerId   | int     |

+-------------+---------+

id 是此表的主键(具有唯一值的列)。

该表的每一行表示雇员的名字、他们的部门和他们的经理的id。

如果managerId为空,则该员工没有经理。

没有员工会成为自己的管理者。

编写一个解决方案,找出至少有五个直接下属的经理。


以 任意顺序 返回结果表。


查询结果格式如下所示。


示例 1:


输入:

Employee 表:

+-----+-------+------------+-----------+

| id  | name  | department | managerId |

+-----+-------+------------+-----------+

| 101 | John  | A          | Null      |

| 102 | Dan   | A          | 101       |

| 103 | James | A          | 101       |

| 104 | Amy   | A          | 101       |

| 105 | Anne  | A          | 101       |

| 106 | Ron   | B          | 101       |

+-----+-------+------------+-----------+

输出:

+------+

| name |

+------+

| John |

+------+

代码SQL如下:

select name 
from Employee 
where id in ( select managerId from Employee group by managerId having count(*)>=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如下:

select T1.user_id,
round(count(if(T2.action = "confirmed",true,null)) / count(*),2) as confirmation_rate
from Signups as T1 left join confirmations as T2
on T1.user_id = T2.user_id
group by T1.user_id;


相关文章
|
2月前
|
SQL 数据库 ice
高频SQL50题(基础版)三
高频SQL50题(基础版)三
|
2月前
|
SQL
高频SQL50题(基础版)
高频SQL50题(基础版)
|
SQL
国际站 SQL Server 发布 标准单机基础版
信息摘要: 国际站 SQL Server 发布 标准单机基础版,提供更高性价比的SQL Server 实例适用客户: 使用SQL Server 的用户,适用于中小企业管理软件,如财务管理、进销存管理、ERP、CRM等系统。
850 0
|
SQL Web App开发 数据库
|
3月前
|
关系型数据库 MySQL 网络安全
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
|
5月前
|
SQL 存储 监控
SQL Server的并行实施如何优化?
【7月更文挑战第23天】SQL Server的并行实施如何优化?
135 13
|
5月前
|
SQL
解锁 SQL Server 2022的时间序列数据功能
【7月更文挑战第14天】要解锁SQL Server 2022的时间序列数据功能,可使用`generate_series`函数生成整数序列,例如:`SELECT value FROM generate_series(1, 10)。此外,`date_bucket`函数能按指定间隔(如周)对日期时间值分组,这些工具结合窗口函数和其他时间日期函数,能高效处理和分析时间序列数据。更多信息请参考官方文档和技术资料。
|
5月前
|
SQL 存储 网络安全
关系数据库SQLserver 安装 SQL Server
【7月更文挑战第26天】
73 6
|
5月前
|
存储 SQL C++
对比 SQL Server中的VARCHAR(max) 与VARCHAR(n) 数据类型
【7月更文挑战7天】SQL Server 中的 VARCHAR(max) vs VARCHAR(n): - VARCHAR(n) 存储最多 n 个字符(1-8000),适合短文本。 - VARCHAR(max) 可存储约 21 亿个字符,适合大量文本。 - VARCHAR(n) 在处理小数据时性能更好,空间固定。 - VARCHAR(max) 对于大文本更合适,但可能影响性能。 - 选择取决于数据长度预期和业务需求。
469 1
|
5月前
|
SQL Oracle 关系型数据库
MySQL、SQL Server和Oracle数据库安装部署教程
数据库的安装部署教程因不同的数据库管理系统(DBMS)而异,以下将以MySQL、SQL Server和Oracle为例,分别概述其安装部署的基本步骤。请注意,由于软件版本和操作系统的不同,具体步骤可能会有所变化。
387 3