leetcode刷题 - SQL - 简单

目录

[1. 175组合两个表](#1. 175组合两个表)

左外连接

[2. 181. 超过经理收入的员工](#2. 181. 超过经理收入的员工)

[3. 182. 查找重复的电子邮箱](#3. 182. 查找重复的电子邮箱)

[4. 196. 删除重复的电子邮箱](#4. 196. 删除重复的电子邮箱)

[5. 197. 上升的温度](#5. 197. 上升的温度)

日期作差

[6. 511. 游戏玩法分析 I](#6. 511. 游戏玩法分析 I)

[7. 577. 员工奖金](#7. 577. 员工奖金)

null条件运算

[8. 584. 寻找用户推荐人](#8. 584. 寻找用户推荐人)

[9. 586. 订单最多的客户](#9. 586. 订单最多的客户)

[10. 595. 大的国家](#10. 595. 大的国家)

[11. 596. 超过5名学生的课](#11. 596. 超过5名学生的课)

聚合加条件

[🦍12. 607. 销售员](#🦍12. 607. 销售员)

[13. 610. 判断三角形](#13. 610. 判断三角形)

if语句

[14. 619. 只出现一次的最大数字](#14. 619. 只出现一次的最大数字)

仅独立使用select

[15. 620. 有趣的电影](#15. 620. 有趣的电影)

[16. 627.update替换](#16. 627.update替换)

[17. 1050. 合作过至少三次的演员和导演](#17. 1050. 合作过至少三次的演员和导演)

[group by两个参数](#group by两个参数)

[18. 1068. 产品销售分析 I](#18. 1068. 产品销售分析 I)

[19. 1084. 销售分析III](#19. 1084. 销售分析III)

日期比较

[20. 1075. 项目员工 I](#20. 1075. 项目员工 I)

[小数点位数 round(x,2)](#小数点位数 round(x,2))

[21. 1141. 查询近30天活跃用户数](#21. 1141. 查询近30天活跃用户数)

[22. 1148. 文章浏览 I](#22. 1148. 文章浏览 I)

[🦍23. 1179. 重新格式化部门表](#🦍23. 1179. 重新格式化部门表)

行转列暴力解法

[24. 1211. 查询结果的质量和占比](#24. 1211. 查询结果的质量和占比)

分组后求算式

[25. 1251. 平均售价](#25. 1251. 平均售价)

ifnull(算式,空时的值)

[26. 1280. 学生们参加各科测试的次数](#26. 1280. 学生们参加各科测试的次数)

连接多

[27. 1327. 列出指定时间段内所有的下单产品](#27. 1327. 列出指定时间段内所有的下单产品)

日期函数YEAR()

[28. 1378. 使用唯一标识码替换员工ID](#28. 1378. 使用唯一标识码替换员工ID)

[29. 1407. 排名靠前的旅行者](#29. 1407. 排名靠前的旅行者)

陷阱

[30. 1484. 按日期分组销售产品](#30. 1484. 按日期分组销售产品)

[group_concat(distinct product)](#group_concat(distinct product))

[31. 1527. 患某种疾病的患者](#31. 1527. 患某种疾病的患者)

字符串占位符

[32. 1587. 银行账户概要 II](#32. 1587. 银行账户概要 II)

[33. 1581. 进店却未进行过交易的顾客](#33. 1581. 进店却未进行过交易的顾客)

null统计不到个数,要使用count(*)

[34. 1517. 查找拥有有效邮箱的用户](#34. 1517. 查找拥有有效邮箱的用户)

正则表达式!🌿!

[35. 1633. 各赛事的用户注册率](#35. 1633. 各赛事的用户注册率)

[36. 1661. 每台机器的进程平均运行时间](#36. 1661. 每台机器的进程平均运行时间)

[37. 1667. 修复表中的名字](#37. 1667. 修复表中的名字)

[38. 1683. 无效的推文](#38. 1683. 无效的推文)

[39. 1693. 每天的领导和合伙人](#39. 1693. 每天的领导和合伙人)

[40. 1729. 求关注者的数量](#40. 1729. 求关注者的数量)

[41. 1731. 每位经理的下属员工数量](#41. 1731. 每位经理的下属员工数量)

[42. 1741. 查找每个员工花费的总时间](#42. 1741. 查找每个员工花费的总时间)

[43. 1757. 可回收且低脂的产品](#43. 1757. 可回收且低脂的产品)

[44. 1789. 员工的直属部门](#44. 1789. 员工的直属部门)

union

[45.🦍 1795. 每个产品在不同商店的价格](#45.🦍 1795. 每个产品在不同商店的价格)

[46. 1873. 计算特殊奖金](#46. 1873. 计算特殊奖金)

if嵌套

[47. 1890. 2020年最后一次登录](#47. 1890. 2020年最后一次登录)

[48.1965. 丢失信息的雇员](#48.1965. 丢失信息的雇员)

[49. 1978. 上级经理已离职的公司员工](#49. 1978. 上级经理已离职的公司员工)

[50. 2356. 每位教师所教授的科目种类的数量](#50. 2356. 每位教师所教授的科目种类的数量)

1. 175组合两个表

左外连接

Q:

表: Person

+-------------+---------+
| 列名         | 类型     |
+-------------+---------+
| PersonId    | int     |
| FirstName   | varchar |
| LastName    | varchar |
+-------------+---------+
personId 是该表的主键(具有唯一值的列)。
该表包含一些人的 ID 和他们的姓和名的信息。
 

表: Address

+-------------+---------+
| 列名         | 类型    |
+-------------+---------+
| AddressId   | int     |
| PersonId    | int     |
| City        | varchar |
| State       | varchar |
+-------------+---------+
addressId 是该表的主键(具有唯一值的列)。
该表的每一行都包含一个 ID = PersonId 的人的城市和州的信息。
 

编写解决方案,报告 Person 表中每个人的姓、名、城市和州。如果 personId 的地址不在 Address 表中,则报告为 null 。

以 任意顺序 返回结果表。

结果格式如下所示。


示例 1:

输入: 
Person表:
+----------+----------+-----------+
| personId | lastName | firstName |
+----------+----------+-----------+
| 1        | Wang     | Allen     |
| 2        | Alice    | Bob       |
+----------+----------+-----------+
Address表:
+-----------+----------+---------------+------------+
| addressId | personId | city          | state      |
+-----------+----------+---------------+------------+
| 1         | 2        | New York City | New York   |
| 2         | 3        | Leetcode      | California |
+-----------+----------+---------------+------------+
输出: 
+-----------+----------+---------------+----------+
| firstName | lastName | city          | state    |
+-----------+----------+---------------+----------+
| Allen     | Wang     | Null          | Null     |
| Bob       | Alice    | New York City | New York |
+-----------+----------+---------------+----------+
解释: 
地址表中没有 personId = 1 的地址,所以它们的城市和州返回 null。
addressId = 1 包含了 personId = 2 的地址信息。
sql 复制代码
SELECT firstName, lastName, city, state from Person left join Address on Person.personId=Address.personId; 
  1. 181. 超过经理收入的员工
sql 复制代码
表:Employee 

+-------------+---------+
| Column Name | Type    |
+-------------+---------+
| id          | int     |
| name        | varchar |
| salary      | int     |
| managerId   | int     |
+-------------+---------+
id 是该表的主键(具有唯一值的列)。
该表的每一行都表示雇员的ID、姓名、工资和经理的ID。
 

编写解决方案,找出收入比经理高的员工。

以 任意顺序 返回结果表。

结果格式如下所示。

 

示例 1:

输入: 
Employee 表:
+----+-------+--------+-----------+
| id | name  | salary | managerId |
+----+-------+--------+-----------+
| 1  | Joe   | 70000  | 3         |
| 2  | Henry | 80000  | 4         |
| 3  | Sam   | 60000  | Null      |
| 4  | Max   | 90000  | Null      |
+----+-------+--------+-----------+
输出: 
+----------+
| Employee |
+----------+
| Joe      |
+----------+
解释: Joe 是唯一挣得比经理多的雇员。
sql 复制代码
SELECT a.name Employee FROM Employee a join Employee b on a.managerId=b.id where a.salary>b.salary;

3. 182. 查找重复的电子邮箱

sql 复制代码
输入: 
Person 表:
+----+---------+
| id | email   |
+----+---------+
| 1  | a@b.com |
| 2  | c@d.com |
| 3  | a@b.com |
+----+---------+
输出: 
+---------+
| Email   |
+---------+
| a@b.com |
+---------+
解释: a@b.com 出现了两次。
sql 复制代码
select email as Email from Person group by email having count(email) > 1
  1. 183. 从不订购的客户
sql 复制代码
select t.name as Customers from (select C.id as i,name,O.id as ii,customerId from Customers as C left join Orders as O on C.id=O.customerId) as t where t.customerId is null
or
select name as Customers from Customers as C left join Orders as O on C.id=O.customerId where O.customerId is null

4. 196. 删除重复的电子邮箱

编写解决方案删除 所有重复的电子邮件,只保留一个具有最小 id 的唯一电子邮件。

(对于 SQL 用户,请注意你应该编写一个 DELETE 语句而不是 SELECT 语句。)

sql 复制代码
| id | email            |
| -- | ---------------- |
| 1  | john@example.com |
| 2  | bob@example.com  |
| 3  | john@example.com |
sql 复制代码
DELETE FROM Person
WHERE id NOT IN (
   # 筛出所有的单个最小id,删掉不在里面的
   SELECT id FROM (
       SELECT MIN(id) AS id FROM Person GROUP BY email
   ) AS u
);

5. 197. 上升的温度

日期作差

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

返回结果 无顺序要求

结果格式如下例子所示。

sql 复制代码
# Write your MySQL query statement below
select t.id1 id from (
    select w1.id id1,w1.recordDate re1,w1.temperature te1,w2.id id2,w2.recordDate re2,w2.temperature te2 
    from Weather as w1 left join Weather as w2 on TIMESTAMPDIFF(DAY,w2.recordDate, w1.recordDate)=1
) as t where t.te1>t.te2

6. 511. 游戏玩法分析 I

sql 复制代码
查询每位玩家 第一次登陆平台的日期。

查询结果的格式如下所示:

Activity 表:
+-----------+-----------+------------+--------------+
| player_id | device_id | event_date | games_played |
+-----------+-----------+------------+--------------+
| 1         | 2         | 2016-03-01 | 5            |
| 1         | 2         | 2016-05-02 | 6            |
| 2         | 3         | 2017-06-25 | 1            |
| 3         | 1         | 2016-03-02 | 0            |
| 3         | 4         | 2018-07-03 | 5            |
+-----------+-----------+------------+--------------+

Result 表:
+-----------+-------------+
| player_id | first_login |
+-----------+-------------+
| 1         | 2016-03-01  |
| 2         | 2017-06-25  |
| 3         | 2016-03-02  |
+-----------+-------------+
sql 复制代码
# Write your MySQL query statement below
select player_id,min(event_date) first_login from(
    select player_id,event_date from Activity
) as t group by player_id

7. 577. 员工奖金

null条件运算

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

sql 复制代码
结果格式如下所示。

 

示例 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 name,bonus from Employee as e left join Bonus as b 
    on e.empId=b.empId 
    where b.bonus < 1000 or b.bonus is null

Q:在这个语句里我筛选出了bonus小于1000的数据,但是bonus为null为什么筛选不出来?

A: 这是因为在MySQL中,当你使用条件筛选时,NULL 值的处理方式会有些不同。通常情况下,比较 NULL 值需要使用IS NULLIS NOT NULL,而不是使用比较运算符(如 <>=)。

8. 584. 寻找用户推荐人

sql 复制代码
找出那些 没有被 id = 2 的客户 推荐 的客户的姓名。
以 任意顺序 返回结果表。
结果格式如下所示。

示例 1:
输入: 
Customer 表:
+----+------+------------+
| id | name | referee_id |
+----+------+------------+
| 1  | Will | null       |
| 2  | Jane | null       |
| 3  | Alex | 2          |
| 4  | Bill | null       |
| 5  | Zack | 1          |
| 6  | Mark | 2          |
+----+------+------------+

easy

9. 586. 订单最多的客户

sql 复制代码
查找下了 最多订单 的客户的 customer_number 。

测试用例生成后, 恰好有一个客户 比任何其他客户下了更多的订单。

查询结果格式如下所示。

 

示例 1:

输入: 
Orders 表:
+--------------+-----------------+
| order_number | customer_number |
+--------------+-----------------+
| 1            | 1               |
| 2            | 2               |
| 3            | 3               |
| 4            | 3               |
+--------------+-----------------+
输出: 
+-----------------+
| customer_number |
+-----------------+
| 3               |
+-----------------+
sql 复制代码
select customer_number
    from orders
    group by customer_number 
    order by count(*) desc
    limit 1

10. 595. 大的国家

如果一个国家满足下述两个条件之一,则认为该国是 大国

  • 面积至少为 300 万平方公里(即,3000000 km2),或者
  • 人口至少为 2500 万(即 25000000)送分题

11. 596. 超过5名学生的课

聚合加条件

sql 复制代码
查询 至少有5个学生 的所有班级。

以 任意顺序 返回结果表。

查询结果格式如下所示。

 

示例 1:

输入: 
Courses table:
+---------+----------+
| student | class    |
+---------+----------+
| A       | Math     |
| B       | English  |
| C       | Math     |
| D       | Biology  |
| E       | Math     |
| F       | Computer |
| G       | Math     |
| H       | Math     |
| I       | Math     |
+---------+----------+
输出: 
+---------+ 
| class   | 
+---------+ 
| Math    | 
+---------+
sql 复制代码
select class from Courses 
    group by class 
    having count(student)>=5

🦍12. 607. 销售员

sql 复制代码
编写解决方案,找出没有任何与名为 "RED" 的公司相关的订单的所有销售人员的姓名。

以 任意顺序 返回结果表。

返回结果格式如下所示。

 

示例 1:

输入:
SalesPerson 表:
+----------+------+--------+-----------------+------------+
| sales_id | name | salary | commission_rate | hire_date  |
+----------+------+--------+-----------------+------------+
| 1        | John | 100000 | 6               | 4/1/2006   |
| 2        | Amy  | 12000  | 5               | 5/1/2010   |
| 3        | Mark | 65000  | 12              | 12/25/2008 |
| 4        | Pam  | 25000  | 25              | 1/1/2005   |
| 5        | Alex | 5000   | 10              | 2/3/2007   |
+----------+------+--------+-----------------+------------+
Company 表:
+--------+--------+----------+
| com_id | name   | city     |
+--------+--------+----------+
| 1      | RED    | Boston   |
| 2      | ORANGE | New York |
| 3      | YELLOW | Boston   |
| 4      | GREEN  | Austin   |
+--------+--------+----------+
Orders 表:
+----------+------------+--------+----------+--------+
| order_id | order_date | com_id | sales_id | amount |
+----------+------------+--------+----------+--------+
| 1        | 1/1/2014   | 3      | 4        | 10000  |
| 2        | 2/1/2014   | 4      | 5        | 5000   |
| 3        | 3/1/2014   | 1      | 1        | 50000  |
| 4        | 4/1/2014   | 1      | 4        | 25000  |
+----------+------------+--------+----------+--------+
输出:
+------+
| name |
+------+
| Amy  |
| Mark |
| Alex |
+------+
sql 复制代码
select tem.name name from (
    select s.sales_id id,s.name name,o.com_id com_id  from SalesPerson as s left join Orders as o on s.sales_id=o.sales_id
) as tem left join Company as c on tem.com_id=c.com_id or tem.name is null
group by tem.id
having sum(if(c.name='RED',1,0))=0

13. 610. 判断三角形

if语句

sql 复制代码
输入: 
Triangle 表:
+----+----+----+
| x  | y  | z  |
+----+----+----+
| 13 | 15 | 30 |
| 10 | 20 | 15 |
+----+----+----+
输出: 
+----+----+----+----------+
| x  | y  | z  | triangle |
+----+----+----+----------+
| 13 | 15 | 30 | No       |
| 10 | 20 | 15 | Yes      |
+----+----+----+----------+
sql 复制代码
select x,y,z,(if(x+y>z and x+z>y and y+z>x,'Yes','No')) as triangle from Triangle; 

14. 619. 只出现一次的最大数字

仅独立使用select

sql 复制代码
单一数字 是在 MyNumbers 表中只出现一次的数字。

找出最大的 单一数字 。如果不存在 单一数字 ,则返回 null 。

查询结果如下例所示。

 

示例 1:

输入:
MyNumbers 表:
+-----+
| num |
+-----+
| 8   |
| 8   |
| 3   |
| 3   |
| 1   |
| 4   |
| 5   |
| 6   |
+-----+
输出:
+-----+
| num |
+-----+
| 6   |
+-----+

还有null的情况
sql 复制代码
# Write your MySQL query statement below
select (
  select num from MyNumbers 
  group by num
  having count(num)=1
  order by num desc
  limit 1
) as num

select null as num
| num  |
| ---- |
| null |

15. 620. 有趣的电影

编写解决方案,找出所有影片描述为 boring (不无聊) 的并且id 为奇数的影片。

返回结果按 rating 降序排列

结果格式如下示例。送分题

sql 复制代码
select * from cinema where id%2=1 and description!='boring'
order by rating desc

16. 627.update替换

请你编写一个解决方案来交换所有的 'f''m' (即,将所有 'f' 变为 'm' ,反之亦然),仅使用 单个 update 语句 ,且不产生中间临时表。

注意,你必须仅使用一条 update 语句,且 不能 使用 select 语句。

sql 复制代码
update Salary
set sex = if(sex='m','f','m')

17. 1050. 合作过至少三次的演员和导演

group by两个参数

编写解决方案找出合作过至少三次的演员和导演的 id 对 (actor_id, director_id)

sql 复制代码
# Write your MySQL query statement below
select Ac.actor_id,Ac.director_id from ActorDirector as Ac 
group by Ac.actor_id,Ac.director_id
having count(*)>=3

18. 1068. 产品销售分析 I

送分题

sql 复制代码
select p.product_name,s.year,s.price from Sales as s left join Product as p on s.product_id=p.product_id

19. 1084. 销售分析III

日期比较

2019-01-012019-03-31(含)之间出售的商品。

sql 复制代码
# Write your MySQL query statement below
select t.product_id,p.product_name from (
    select s.product_id from Sales as s
    group by s.product_id having max(s.sale_date)<'2019-04-01' and min(s.sale_date)>='2019-01-01'
) as t left join Product as p on t.product_id=p.product_id

20. 1075. 项目员工 I

小数点位数 round(x,2)

sql 复制代码
Project 表:
+-------------+-------------+
| project_id  | employee_id |
+-------------+-------------+
| 1           | 1           |
| 1           | 2           |
| 1           | 3           |
| 2           | 1           |
| 2           | 4           |
+-------------+-------------+

Employee 表:
+-------------+--------+------------------+
| employee_id | name   | experience_years |
+-------------+--------+------------------+
| 1           | Khaled | 3                |
| 2           | Ali    | 2                |
| 3           | John   | 1                |
| 4           | Doe    | 2                |
+-------------+--------+------------------+

Result 表:
+-------------+---------------+
| project_id  | average_years |
+-------------+---------------+
| 1           | 2.00          |
| 2           | 2.50          |
+-------------+---------------+
第一个项目中,员工的平均工作年限是 (3 + 2 + 1) / 3 = 2.00;第二个项目中,员工的平均工作年限是 (3 + 2) / 2 = 2.50
sql 复制代码
select p.project_id,round(avg(e.experience_years),2) as average_years from Project as p join Employee as e on p.employee_id=e.employee_id
group by p.project_id

21. 1141. 查询近30天活跃用户数

编写解决方案,统计截至 2019-07-27(包含2019-07-27),近30 天的每日活跃用户数(当天只要有一条活动记录,即为活跃用户)

输入:
Activity table:
+---------+------------+---------------+---------------+
| user_id | session_id | activity_date | activity_type |
+---------+------------+---------------+---------------+
| 1       | 1          | 2019-07-20    | open_session  |
| 1       | 1          | 2019-07-20    | scroll_down   |
| 1       | 1          | 2019-07-20    | end_session   |
| 2       | 4          | 2019-07-20    | open_session  |
| 2       | 4          | 2019-07-21    | send_message  |
| 2       | 4          | 2019-07-21    | end_session   |
| 3       | 2          | 2019-07-21    | open_session  |
| 3       | 2          | 2019-07-21    | send_message  |
| 3       | 2          | 2019-07-21    | end_session   |
| 4       | 3          | 2019-06-25    | open_session  |
| 4       | 3          | 2019-06-25    | end_session   |
+---------+------------+---------------+---------------+
输出:
+------------+--------------+ 
| day        | active_users |
+------------+--------------+ 
| 2019-07-20 | 2            |
| 2019-07-21 | 2            |
+------------+--------------+ 
sql 复制代码
select day,count(active_users) as active_users from (
select distinct a.activity_date as day,a.user_id as active_users from Activity as a
where a.activity_date>'2019-06-27' and a.activity_date<'2019-07-28'
)as t
group by day 

22. 1148. 文章浏览 I

请查询出所有浏览过自己文章的作者

秒了

sql 复制代码
输入:
Views 表:
+------------+-----------+-----------+------------+
| article_id | author_id | viewer_id | view_date  |
+------------+-----------+-----------+------------+
| 1          | 3         | 5         | 2019-08-01 |
| 1          | 3         | 6         | 2019-08-02 |
| 2          | 7         | 7         | 2019-08-01 |
| 2          | 7         | 6         | 2019-08-02 |
| 4          | 7         | 1         | 2019-07-22 |
| 3          | 4         | 4         | 2019-07-21 |
| 3          | 4         | 4         | 2019-07-21 |
+------------+-----------+-----------+------------+

输出:
+------+
| id   |
+------+
| 4    |
| 7    |
+------+
sql 复制代码
select distinct v.viewer_id as id from Views as v
where v.author_id=v.viewer_id
order by id

🦍23. 1179. 重新格式化部门表

行转列暴力解法

sql 复制代码
SELECT
DISTINCT 
    a.id,
    Jan.revenue AS Jan_Revenue,
    Feb.revenue AS Feb_Revenue,
    Mar.revenue AS Mar_Revenue,
    Apr.revenue AS Apr_Revenue,
    May.revenue AS May_Revenue,
    Jun.revenue AS Jun_Revenue,
    Jul.revenue AS Jul_Revenue,
    Aug.revenue AS Aug_Revenue,
    Sep.revenue AS Sep_Revenue,
    Octo.revenue AS Oct_Revenue,
    Nov.revenue AS Nov_Revenue,
    Dece.revenue AS Dec_Revenue
FROM
    Department a LEFT JOIN Department Jan ON a.id = Jan.id
AND
    Jan.month = 'Jan'LEFT JOIN Department Feb ON a.id = Feb.id
AND
    Feb.month = 'Feb' LEFT JOIN Department Mar ON a.id = Mar.id
AND
    Mar.month = 'Mar' LEFT JOIN Department Apr ON a.id = Apr.id
AND
    Apr.month = 'Apr' LEFT JOIN Department May ON a.id = May.id
AND
    May.month = 'May' LEFT JOIN Department Jun ON a.id = Jun.id
AND
    Jun.month = 'Jun' LEFT JOIN Department Jul ON a.id = Jul.id
AND
    Jul.month = 'Jul' LEFT JOIN Department Aug ON a.id = Aug.id
AND
    Aug.month = 'Aug' LEFT JOIN Department Sep ON a.id = Sep.id
AND
    Sep.month = 'Sep' LEFT JOIN Department Octo ON a.id = Octo.id
AND
    Octo.month = 'Oct'LEFT JOIN Department Nov ON  a.id = Nov.id
AND
    Nov.month = 'Nov' LEFT JOIN Department Dece ON a.id = Dece.id
AND
    Dece.month = 'Dec'

当一个单元格中有多个数据时,case when只会提取当中的第一个数据

那该如何解决单元格内含多个数据的情况呢?答案就是使用聚合函数,聚合函数就用来输入多个数据,输出一个数据的。如SUM()或MAX(),而每个聚合函数的输入就是每一个多数据的单元格。

24. 1211. 查询结果的质量和占比

分组后求算式

sql 复制代码
将查询结果的质量 quality 定义为:

各查询结果的评分与其位置之间比率的平均值。

将劣质查询百分比 poor_query_percentage 为:

评分小于 3 的查询结果占全部查询结果的百分比。
输入:
Queries table:
+------------+-------------------+----------+--------+
| query_name | result            | position | rating |
+------------+-------------------+----------+--------+
| Dog        | Golden Retriever  | 1        | 5      |
| Dog        | German Shepherd   | 2        | 5      |
| Dog        | Mule              | 200      | 1      |
| Cat        | Shirazi           | 5        | 2      |
| Cat        | Siamese           | 3        | 3      |
| Cat        | Sphynx            | 7        | 4      |
+------------+-------------------+----------+--------+
输出:
+------------+---------+-----------------------+
| query_name | quality | poor_query_percentage |
+------------+---------+-----------------------+
| Dog        | 2.50    | 33.33                 |
| Cat        | 0.66    | 33.33                 |
+------------+---------+-----------------------+
解释:
Dog 查询结果的质量为 ((5 / 1) + (5 / 2) + (1 / 200)) / 3 = 2.50
Dog 查询结果的劣质查询百分比为 (1 / 3) * 100 = 33.33

Cat 查询结果的质量为 ((2 / 5) + (3 / 3) + (4 / 7)) / 3 = 0.66
Cat 查询结果的劣质查询百分比为 (1 / 3) * 100 = 33.33
sql 复制代码
select query_name,round(avg(rating/position),2) as quality,round(sum(if(rating<3,1,0))/count(rating)*100,2) as poor_query_percentage 
from Queries
group by query_name 

25. 1251. 平均售价

ifnull(算式,空时的值)

计算题

sql 复制代码
示例 1:

输入:
Prices table:
+------------+------------+------------+--------+
| product_id | start_date | end_date   | price  |
+------------+------------+------------+--------+
| 1          | 2019-02-17 | 2019-02-28 | 5      |
| 1          | 2019-03-01 | 2019-03-22 | 20     |
| 2          | 2019-02-01 | 2019-02-20 | 15     |
| 2          | 2019-02-21 | 2019-03-31 | 30     |
+------------+------------+------------+--------+
UnitsSold table:
+------------+---------------+-------+
| product_id | purchase_date | units |
+------------+---------------+-------+
| 1          | 2019-02-25    | 100   |
| 1          | 2019-03-01    | 15    |
| 2          | 2019-02-10    | 200   |
| 2          | 2019-03-22    | 30    |
+------------+---------------+-------+
输出:
+------------+---------------+
| product_id | average_price |
+------------+---------------+
| 1          | 6.96          |
| 2          | 16.96         |
+------------+---------------+
解释:
平均售价 = 产品总价 / 销售的产品数量。
产品 1 的平均售价 = ((100 * 5)+(15 * 20) )/ 115 = 6.96
产品 2 的平均售价 = ((200 * 15)+(30 * 30) )/ 230 = 16.96
sql 复制代码
# Write your MySQL query statement below
select p.product_id as product_id,ifnull(round(sum(u.units*p.price) / sum(u.units),2),0) as average_price 
from Prices as p left join UnitsSold as u
on u.purchase_date <= p.end_date and u.purchase_date>=p.start_date and u.product_id=p.product_id
group by p.product_id

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

连接多

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 tem.student_id,tem.student_name,tem.subject_name,sum(if (tem.subject_name=cishu.subject_name,1,0)) as attended_exams from (
    select stu.student_id as student_id,stu.student_name as student_name,sub.subject_name as subject_name from Students as stu join Subjects as sub
) as tem left join Examinations as cishu on tem.student_id=cishu.student_id and tem.subject_name=cishu.subject_name
group by  tem.student_id,tem.subject_name
order by tem.student_id,tem.subject_name

27. 1327. 列出指定时间段内所有的下单产品

日期函数YEAR()

sql 复制代码
select p.product_name,t.unit from (
    select product_id,sum(unit) unit from Orders
    where MONTH(order_date)=2 and YEAR(order_date)=2020
    group by product_id
    having sum(unit)>=100
)as t left join Products as p on t.product_id=p.product_id

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

秒了送分题

sql 复制代码
select uni.unique_id as unique_id,e.name from Employees as e left join EmployeeUNI as uni on e.id=uni.id

29. 1407. 排名靠前的旅行者

陷阱

sql 复制代码
编写解决方案,报告每个用户的旅行距离。

返回的结果表单,以 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                  |
+----------+--------------------+
sql 复制代码
# Write your MySQL query statement below
select user.name name,IFNULL(sum(distance),0) travelled_distance
from Users user left join Rides r on r.user_id = user.id
group by user.id
order by travelled_distance desc,name

30. 1484. 按日期分组销售产品

group_concat(distinct product)

sql 复制代码
select sell_date,count(distinct product) num_sold,group_concat(distinct product) products from Activities 
group by sell_date

GROUP_CONCAT 是 MySQL 中的聚合函数,用于将分组后的结果集中的多个行合并成一个字符串,并以指定的分隔符分隔它们。它的一般语法如下:

sql 复制代码
GROUP_CONCAT(column_name [ORDER BY column_name] [SEPARATOR separator])
  • column_name:要合并的列的名称。
  • ORDER BY column_name:可选,用于指定如何对合并的值进行排序。
  • SEPARATOR separator:可选,用于指定合并后的字符串中的分隔符。

以下是一个示例,假设我们有一个名为 "students" 的表,其中包含学生的姓名,并且每个学生都属于一个特定的班级:

sql 复制代码
SELECT class_id, 
       GROUP_CONCAT(student_name ORDER BY student_name SEPARATOR ',') AS students 
FROM students GROUP BY class_id;

31. 1527. 患某种疾病的患者

字符串占位符

查询患有 I 类糖尿病的患者 ID (patient_id)、患者姓名(patient_name)以及其患有的所有疾病代码(conditions)。I 类糖尿病的代码总是包含前缀 DIAB1 。

按 任意顺序 返回结果表。

查询结果格式如下示例所示。

 

示例 1:

输入:
Patients表:
+------------+--------------+--------------+
| patient_id | patient_name | conditions   |
+------------+--------------+--------------+
| 1          | Daniel       | YFEV COUGH   |
| 2          | Alice        |              |
| 3          | Bob          | DIAB100 MYOP |
| 4          | George       | ACNE DIAB100 |
| 5          | Alain        | DIAB201      |
+------------+--------------+--------------+
输出:
+------------+--------------+--------------+
| patient_id | patient_name | conditions   |
+------------+--------------+--------------+
| 3          | Bob          | DIAB100 MYOP |
| 4          | George       | ACNE DIAB100 | 
+------------+--------------+--------------+
解释:Bob 和 George 都患有代码以 DIAB1 开头的疾病。
sql 复制代码
select * from Patients
where conditions like 'DIAB1%' or conditions like '% DIAB1%'

32. 1587. 银行账户概要 II

送分题

sql 复制代码
select Users.name as NAME,tem.BALANCE from (
    select account, sum(amount) as BALANCE from Transactions as t
    group by account 
    having sum(amount)>10000) as tem join Users on tem.account=Users.account 

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

null统计不到个数,要使用count(*)

sql 复制代码
有一些顾客可能光顾了购物中心但没有进行交易。请你编写一个解决方案,来查找这些顾客的 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 v.customer_id,count(*) as count_no_trans from Visits as v left join Transactions as t on v.visit_id=t.visit_id
where t.transaction_id is null
group by v.customer_id

34. 1517. 查找拥有有效邮箱的用户

正则表达式!🌿!

sql 复制代码
select * from Users 
where mail regexp '^[a-zA-Z]+[a-zA-Z0-9_\\.\\/\\-]*@leetcode\\.com$';

35. 1633. 各赛事的用户注册率

算数

sql 复制代码
select contest_id,round(100*count(user.user_name)/(select count(*) from Users),2) as percentage 
from Register as re left join Users as user on re.user_id = user.user_id
group by re.contest_id
order by percentage desc,contest_id

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

作差,思路清奇

sql 复制代码
输入:
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
sql 复制代码
select machine_id,round(sum(if(activity_type='start',-timestamp,timestamp))/(0.5*count(process_id)),3) as processing_time from Activity
group by machine_id

37. 1667. 修复表中的名字

大小写转换

sql 复制代码
# Write your MySQL query statement below
select user_id, concat(upper(left(name,1)),lower(right(name,length(name)-1))) as name from Users
order by user_id 

38. 1683. 无效的推文

送分题

sql 复制代码
select tweet_id from Tweets
where length(content)>15

39. 1693. 每天的领导和合伙人

好几个去重

其实没必要对日期去重,后面的已经去过了

sql 复制代码
# Write your MySQL query statement below
select distinct date_id,make_name,count(distinct lead_id) unique_leads,count(distinct partner_id) unique_partners from DailySales 
group by date_id,make_name

40. 1729. 求关注者的数量

sql 复制代码
select user_id,count(follower_id) as followers_count from Followers
group by user_id
order by user_id

41. 1731. 每位经理的下属员工数量

sql 复制代码
对于此问题,我们将至少有一个其他员工需要向他汇报的员工,视为一个经理。

编写SQL查询需要听取汇报的所有经理的ID、名称、直接向该经理汇报的员工人数,以及这些员工的平均年龄,其中该平均年龄需要四舍五入到最接近的整数。

返回的结果集需要按照 employee_id 进行排序。

查询结果的格式如下:

 

Employees table:
+-------------+---------+------------+-----+
| employee_id | name    | reports_to | age |
+-------------+---------+------------+-----+
| 9           | Hercy   | null       | 43  |
| 6           | Alice   | 9          | 41  |
| 4           | Bob     | 9          | 36  |
| 2           | Winston | null       | 37  |
+-------------+---------+------------+-----+

Result table:
+-------------+-------+---------------+-------------+
| employee_id | name  | reports_count | average_age |
+-------------+-------+---------------+-------------+
| 9           | Hercy | 2             | 39          |
+-------------+-------+---------------+-------------+
Hercy 有两个需要向他汇报的员工, 他们是 Alice and Bob. 他们的平均年龄是 (41+36)/2 = 38.5, 四舍五入的结果是 39.
sql 复制代码
select tem.id1 employee_id,tem.name1 name,count(tem.id2) reports_count,round(avg(tem.age2),0) average_age from 
(select e1.employee_id id1,e1.name name1,e1.reports_to to1,e1.age age1,
        e2.employee_id id2,e2.name name2,e2.reports_to to2,e2.age age2 from Employees as e1 left join Employees as e2 on e1.employee_id=e2.reports_to
where e2.employee_id is not null) tem
group by tem.id1
order by employee_id

42. 1741. 查找每个员工花费的总时间

送分

sql 复制代码
select event_day day, emp_id,sum(out_time-in_time) total_time from Employees
group by event_day,emp_id

43. 1757. 可回收且低脂的产品

送分

sql 复制代码
select product_id from Products
where low_fats='Y' and recyclable='Y'

44. 1789. 员工的直属部门

union

sql 复制代码
select employee_id, min(department_id) department_id from Employee
group by employee_id
having count(primary_flag) = 1
union
select employee_id, department_id from Employee
where primary_flag = 'Y'

45.🦍 1795. 每个产品在不同商店的价格

sql 复制代码
请你重构 Products 表,查询每个产品在不同商店的价格,使得输出的格式变为(product_id, store, price) 。如果这一产品在商店里没有出售,则不输出这一行。

输出结果表中的 顺序不作要求 。

查询输出格式请参考下面示例。

 

示例 1:

输入:
Products table:
+------------+--------+--------+--------+
| product_id | store1 | store2 | store3 |
+------------+--------+--------+--------+
| 0          | 95     | 100    | 105    |
| 1          | 70     | null   | 80     |
+------------+--------+--------+--------+
输出:
+------------+--------+-------+
| product_id | store  | price |
+------------+--------+-------+
| 0          | store1 | 95    |
| 0          | store2 | 100   |
| 0          | store3 | 105   |
| 1          | store1 | 70    |
| 1          | store3 | 80    |
+------------+--------+-------+
解释:
产品 0 在 store1、store2、store3 的价格分别为 95、100、105。
产品 1 在 store1、store3 的价格分别为 70、80。在 store2 无法买到。

行列转换

sql 复制代码
# Write your MySQL query statement below
select product_id, 'store1' as store, store1 as price from Products where store1 is not null
union all
select product_id, 'store2' as store, store2 as price from Products where store2 is not null
union all
select product_id, 'store3' as store, store3 as price from Products where store3 is not null

46. 1873. 计算特殊奖金

if嵌套

sql 复制代码
select employee_id,if(employee_id%2=1,if(left(name,1)!='M',salary,0),0) bonus from Employees 
order by employee_id

47. 1890. 2020年最后一次登录

sql 复制代码
select user_id ,max(time_stamp) last_stamp from Logins
where time_stamp>='2020-01-01 00:00:00' and time_stamp<='2020-12-31 23:59:59'
group by user_id 

48.1965. 丢失信息的雇员

第七穿插连

sql 复制代码
select employee_id from Employees where employee_id not in (select employee_id from salaries)
union
select employee_id from Salaries where employee_id not in (select employee_id from Employees)
order by employee_id

49. 1978. 上级经理已离职的公司员工

sql 复制代码
查找这些员工的id,他们的薪水严格少于$30000 并且他们的上级经理已离职。当一个经理离开公司时,他们的信息需要从员工表中删除掉,但是表中的员工的manager_id  这一列还是设置的离职经理的id 。

返回的结果按照employee_id 从小到大排序。

查询结果如下所示:

 

示例:

输入:
Employees table:
+-------------+-----------+------------+--------+
| employee_id | name      | manager_id | salary |
+-------------+-----------+------------+--------+
| 3           | Mila      | 9          | 60301  |
| 12          | Antonella | null       | 31000  |
| 13          | Emery     | null       | 67084  |
| 1           | Kalel     | 11         | 21241  |
| 9           | Mikaela   | null       | 50937  |
| 11          | Joziah    | 6          | 28485  |
+-------------+-----------+------------+--------+
输出:
+-------------+
| employee_id |
+-------------+
| 11          |
+-------------+

解释:
薪水少于 30000 美元的员工有 1 号(Kalel) 和 11号 (Joziah)。
Kalel 的上级经理是 11 号员工,他还在公司上班(他是 Joziah )。
Joziah 的上级经理是 6 号员工,他已经离职,因为员工表里面已经没有 6 号员工的信息了,它被删除了。

表述不清

sql 复制代码
select e.employee_id
from Employees e
left join Employees ee
on e.manager_id = ee.employee_id
where e.manager_id is not null and  ee.employee_id is null and e.salary < 30000
order by e.employee_id

50. 2356. 每位教师所教授的科目种类的数量

sql 复制代码
select teacher_id,count(distinct subject_id) cnt from Teacher
group by teacher_id
相关推荐
Gentle5862 分钟前
labview中连接sql server数据库查询语句
数据库·labview
Gentle5863 分钟前
labview用sql server数据库存取数据到一个单元格
数据库·labview
2401_857636396 分钟前
共享汽车管理新纪元:SpringBoot框架应用
数据库·spring boot·汽车
菲兹园长6 分钟前
表的设计(MYSQL)
数据库·mysql
Java Fans21 分钟前
MySQL数据库常用命令大全(完整版——表格形式)
数据库·mysql
起飞的风筝34 分钟前
【redis】—— 环境搭建教程
数据库·redis·缓存
白萝卜弟弟37 分钟前
【MySQL】MySQL函数之JSON_EXTRACT
数据库·mysql·json
gjh120839 分钟前
MySQL常见面试题
数据库·mysql
我的K84091 小时前
Flink整合Hive、Mysql、Hbase、Kafka
hive·mysql·flink
Rverdoser2 小时前
Python & PyQt5 实现 .his 文件批量转 Excel 工具
数据库