编程题——数据库(LeetCode简单)

本文探讨了多个复杂的SQL查询案例,包括查找收入超过经理的员工、检测重复电子邮件、识别未下订单的客户等,通过实际例子展示了如何利用SQL解决实际问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

超过经理收入的员工

查找重复的电子邮箱

从不订购的客户


  • 超过经理收入的员工

题目描述:Employee 表包含所有员工,他们的经理也属于员工。每个员工都有一个 Id,此外还有一列对应员工的经理的 Id。

+----+-------+--------+-----------+
| Id | Name  | Salary | ManagerId |
+----+-------+--------+-----------+
| 1  | Joe   | 70000  | 3         |
| 2  | Henry | 80000  | 4         |
| 3  | Sam   | 60000  | NULL      |
| 4  | Max   | 90000  | NULL      |
+----+-------+--------+-----------+

给定 Employee 表,编写一个 SQL 查询,该查询可以获取收入超过他们经理的员工的姓名。在上面的表格中,Joe 是唯一一个收入超过他的经理的员工。

+----------+
| Employee |
+----------+
| Joe      |
+----------+

解题代码:

SELECT a.Name AS Employee
FROM Employee a,Employee b
WHERE a.ManagerId = b.Id 
AND a.Salary > b.Salary;

解题思路:

  1. FROM 两个一模一样的Employee表 a, b
  2. WHERE 和 AND的基本用法

  • 查找重复的电子邮箱

题目描述:编写一个 SQL 查询,查找 Person 表中所有重复的电子邮箱。

+----+---------+
| Id | Email   |
+----+---------+
| 1  | a@b.com |
| 2  | c@d.com |
| 3  | a@b.com |
+----+---------+

根据以上输入,你的查询应返回以下结果:

+---------+
| Email   |
+---------+
| a@b.com |
+---------+

说明:所有电子邮箱都是小写字母

解题代码一:

SELECT Email     
From (SELECT Email, count(Email) as num
     From Person
     GROUP BY Email) AS statistic
WHERE num > 1;

解题思路:

括号里的SELECT语句是产生一个临时表,如下

| Email   | num |
|---------|-----|
| a@b.com | 2   |
| c@d.com | 1   |

statistic,用来对查询计划进行优化的,一般会统计表中的记录数、表的 大小,字段不同值的数量等。在这里statistic的作用就是作为临时表的别名,这个是不能省略的,如果省略会报错。

GROUP BY 和count一般都会同时出现在一个SELECT语句中。

解题代码二(推荐):

SELECT Email
From Person
GROUP BY Email
having count(Email) > 1;

解题思路:

  1. 用了having这条语句就避免了创造临时表。
  2. having 筛选行。
  3. 只要用了GROUP BY(某列)就可以直接用count(某列)就可以数重复的行数了。

  • 从不订购的客户

题目描述:某网站包含两个表,Customers 表和 Orders 表。编写一个 SQL 查询,找出所有从不订购任何东西的客户。

Customers 表:

+----+-------+
| Id | Name  |
+----+-------+
| 1  | Joe   |
| 2  | Henry |
| 3  | Sam   |
| 4  | Max   |
+----+-------+

Orders 表

+----+------------+
| Id | CustomerId |
+----+------------+
| 1  | 3          |
| 2  | 1          |
+----+------------+

例如给定上述表格,你的查询应返回

+-----------+
| Customers |
+-----------+
| Henry     |
| Max       |
+-----------+

解题代码:

select c.Name AS 'Customers'
from Customers c
where c.Id not in
(
    select o.CustomerId from Orders o

);

解题思路:

  1. not in + 某表的咧
  2. where xxx not in 表.列

  • 删除重复的电子邮箱

题目描述:编写一个 SQL 查询,来删除 Person 表中所有重复的电子邮箱,重复的邮箱里只保留 Id 最小 的那个。

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
| 3  | john@example.com |
+----+------------------+
Id 是这个表的主键。

例如,在运行你的查询语句之后,上面的Person表返回以下几行

+----+------------------+
| Id | Email            |
+----+------------------+
| 1  | john@example.com |
| 2  | bob@example.com  |
+----+------------------+

解题代码:

delete p1
from Person p1, Person p2
where p1.Email = p2.Email and p1.Id > p2.Id

解题思路:

经典题,要考。用两个一模一样的表来找出满足条件的行。


  • 上升的温度

题目描述:给定一个 Weather 表,编写一个 SQL 查询,来查找与之前(昨天的)日期相比温度更高的所有日期的 Id。

+---------+------------------+------------------+
| Id(INT) | RecordDate(DATE) | Temperature(INT) |
+---------+------------------+------------------+
|       1 |       2015-01-01 |               10 |
|       2 |       2015-01-02 |               25 |
|       3 |       2015-01-03 |               20 |
|       4 |       2015-01-04 |               30 |
+---------+------------------+------------------+

例如,根据上述给定的 Weather 表格,返回如下 Id:

+----+
| Id |
+----+
|  2 |
|  4 |
+----+

 解题代码一:

select distinct w1.id
from Weather w1,Weather w2
where w1.RecordDate > w2.RecordDate and DATEDIFF(w1.RecordDate, w2.RecordDate) = 1  
and w1.Temperature > w2.Temperature

解题思路:

  1. 思路和上一道题相似
  2. 这里用到一个新的关键字 DATEDIFF(date1, date2) == 1表示两个日期相差一天

解题代码二:

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值