【SQL高频练习带刷】day7:子查询

        子查询可以用在SELECT、INSERT、UPDATE、DELETE语句中,以及在WHERE子句、HAVING子句或FROM子句中,以实现数据的关联和过滤。

题目一:上级经理已离职的公司员工

题目要求:

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

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

表结构:

 运行结果示例:

思路:

        只需要查询存在manager_id并且该id不在employee_id里的数据即可,再加上工资的限定条件。

运行代码示例:

select employee_id
from Employees
where manager_id is not null and manager_id not in (select employee_id from Employees) and salary < 30000
order by employee_id

题目二:换座位

题目要求:

编写解决方案来交换每两个连续的学生的座位号。如果学生的数量是奇数,则最后一个学生的id不交换。

按 id 升序 返回结果表。

表结构:

 运行结果示例:

思路:

        这道题乍一看有点难,但是我们坚信“不会做,就找规律”,观察示例,可以看出,除最后一名学生外,其余学生如果学号为奇数,则加一,如果为偶数,则减一。剩下的最后一名学生如果是奇数则不变,是偶数则符合上述规律。这么一看是不是就简单了很多?我们只需要判断id是否为奇数/偶数/奇数且等于总数这三种情况,分别讨论即可。但是我们需要先查询出总数,所以要用到子查询。

运行代码示例:

SELECT (CASE 
            WHEN MOD(id,2) = 1 AND id = (SELECT COUNT(*) FROM seat) THEN id
            WHEN MOD(id,2) = 1 THEN id+1
            ElSE id-1
        END) AS id, student
FROM seat
ORDER BY id;

题目三:电影评分

题目要求:

请你编写一个解决方案:

  • 查找评论电影数量最多的用户名。如果出现平局,返回字典序较小的用户名。
  • 查找在 February 2020 平均评分最高 的电影名称。如果出现平局,返回字典序较小的电影名称。

字典序 ,即按字母在字典中出现顺序对字符串排序,字典序较小则意味着排序靠前。

表结构:

 运行结果示例:

思路:

        首先拆解题目,题目要求查找两部分内容,我们可以分别进行查找,然后union联合一下结果(注意重命名列名)。

        下一步是解决按照字典序返回的问题,其实这一步我们无需进行额外处理,直接order by 就可以了,我们用用户名和电影名作为排序字段时,默认会根据字典序进行排序。

        继而是对“平局”情况的处理,我们只需要先按照数量排序,再按照名称排序,使用limit子句限制查询结果为1即可。

        再来就没有什么难点了,两表连接查询就可以。需要注意的是测试用例中存在用户名与电影名相同的情况,此时使用union会去除掉重复结果,只查询出一个值,因此要使用union  all保留重复值。

运行代码示例:

# 找到评论数最多的人
(select name as results
from  MovieRating m
join Users u
using(user_id)
group by m.user_id
order by count(user_id) desc ,name
limit 1)
union all
# 找到平均评分最高的电影
(select title
from MovieRating
join Movies
using(movie_id)
where created_at between '2020-02-01' and '2020-02-29'
group by movie_id
order by avg(rating) desc, title 
limit 1)

题目四:好友申请--谁有更多的好友

题目要求:

编写解决方案,找出拥有最多的好友的人和他拥有的好友数目。

生成的测试用例保证拥有最多好友数目的只有 1 个人。

表结构:

 运行结果示例:

思路:

        这道题我一开始误解了题目的意思,还觉得这么简单的题也会出....果然是我天真了。题目给出的两个id分别是请求id和通过id,也就是申请好友--通过申请的过程,这样一条数据意味着两个id的用户成为了“彼此”的好有。因此,我们在统计时,也要兼顾两方。进一步,我们可以想到,我们只需要把所有的id都取出来,找出现次数最多的那个id即可。

        (本题目中,默认不存在1主动添加2,2又添加了1的情况,也就是不存在一对好友被计算了两遍;此外,表中所有数据一定是已通过的好友申请,不存在只申请未通过的情况。)

运行代码示例:

select requester_id id,count(accepter_id) num
from RequestAccepted
group by requester_id
order by count(accepter_id) desc
limit 1

<think>好的,用户想了解工作中常用的SQL练习。首先,我需要确定用户的需求。他们可能刚开始学习SQL,或者想在工作中提升自己的查询能力。需要介绍常见的练习内容,确保覆盖实际工作场景中的常见操作。 用户可能对哪些方面感兴趣呢?基础操作肯定是必须的,比如SELECT、WHERE、JOIN这些。然后是分组聚合,因为数据分析中经常用到GROUP BY和聚合函数。子查询和CTE也是高级查询中常用的,应该包括进去。 窗口函数在数据处理中很重要,尤其是在排名和分区计算时,用户可能需要这方面的练习。表操作如创建、修改表结构,还有插入更新数据,这些也是日常维护的一部分。优化部分,比如索引和执行计划,能帮助用户提高查询效率,但可能对初学者稍难,不过还是有必要提一下。 实际应用场景的例子会更具体,比如销售数据或用户行为分析,这样用户可以更直观地理解如何应用SQL练习题的设计需要由浅入深,从简单查询到复杂分析,逐步提升难度。同时,推荐学习资源可以帮助用户自主学习,比如LeetCode、牛客网这些平台。 需要确保语言简洁明了,避免使用专业术语过多,让初学者也能理解。结构上分点列出,每个部分用小标题和代码示例,这样用户看起来清晰。可能用户没有提到的深层需求是希望直接应用到工作中,所以实际例子和练习题特别重要,能帮助他们巩固知识。 最后检查是否有遗漏的部分,比如常见的日期处理、字符串函数,这些在练习中也经常遇到,应该包含进去。还有性能优化部分,虽然进阶但很实用。确认内容全面,覆盖了大多数工作场景,这样用户能得到实用的指导。</think>在工作中进行 SQL 练习时,建议重点关注以下实用场景和常见操作,这些内容能帮助你应对实际工作中的数据处理需求: --- ### **1. 基础查询与过滤** - **SELECT + WHERE** ```sql -- 查询特定条件下的数据(如时间范围、状态) SELECT order_id, customer_name, order_date FROM orders WHERE order_date >= '2023-01-01' AND status = 'completed'; ``` - **DISTINCT 去重** ```sql -- 获取唯一值列表 SELECT DISTINCT department FROM employees; ``` --- ### **2. 分组聚合与统计** - **GROUP BY + 聚合函数** ```sql -- 按部门统计平均工资 SELECT department, AVG(salary) AS avg_salary FROM employees GROUP BY department; ``` - **HAVING 过滤分组结果** ```sql -- 筛选出销售额超过 1 万的部门 SELECT department, SUM(sales) AS total_sales FROM sales_data GROUP BY department HAVING SUM(sales) > 10000; ``` --- ### **3. 多表关联与连接** - **JOIN 操作(INNER/LEFT/RIGHT JOIN)** ```sql -- 关联订单表和客户表 SELECT o.order_id, c.customer_name, o.amount FROM orders o LEFT JOIN customers c ON o.customer_id = c.id; ``` - **自关联查询(如层级数据)** ```sql -- 查询员工及其经理 SELECT e.name AS employee, m.name AS manager FROM employees e LEFT JOIN employees m ON e.manager_id = m.id; ``` --- ### **4. 子查询与 CTE** - **子查询嵌套** ```sql -- 查询工资高于部门平均工资的员工 SELECT name, salary, department FROM employees WHERE salary > (SELECT AVG(salary) FROM employees e2 WHERE e2.department = e1.department); ``` - **CTE(公共表表达式)** ```sql WITH dept_avg AS ( SELECT department, AVG(salary) AS avg_salary FROM employees GROUP BY department ) SELECT e.name, e.salary, d.avg_salary FROM employees e JOIN dept_avg d ON e.department = d.department; ``` --- ### **5. 窗口函数(高级分析)** - **排名(ROW_NUMBER/RANK/DENSE_RANK)** ```sql -- 按销售额给销售员排名 SELECT salesperson, sales, RANK() OVER (ORDER BY sales DESC) AS rank FROM sales; ``` - **累计计算(SUM OVER)** ```sql -- 计算月度销售额累计 SELECT month, sales, SUM(sales) OVER (ORDER BY month) AS cumulative_sales FROM monthly_sales; ``` --- ### **6. 日期与字符串处理** - **日期格式化与计算** ```sql -- 计算订单处理时长(天数) SELECT order_id, DATEDIFF(day, order_date, shipped_date) AS processing_days FROM orders; ``` - **字符串截取与拼接** ```sql -- 合并姓和名 SELECT CONCAT(first_name, ' ', last_name) AS full_name FROM employees; ``` --- ### **7. 数据更新与表操作** - **INSERT/UPDATE/DELETE** ```sql -- 更新用户状态 UPDATE users SET status = 'inactive' WHERE last_login < '2022-01-01'; ``` - **表结构修改(ALTER TABLE)** ```sql -- 添加新列 ALTER TABLE products ADD COLUMN category VARCHAR(50); ``` --- ### **8. 性能优化技巧** - **索引的使用场景** ```sql -- 为高频查询字段创建索引 CREATE INDEX idx_customer_id ON orders (customer_id); ``` - **EXPLAIN 分析执行计划** ```sql EXPLAIN SELECT * FROM orders WHERE customer_id = 1001; ``` --- ### **实际场景练习建议** 1. **模拟业务数据**(如电商、金融、用户行为数据) - 分析用户留存率、销售额趋势、产品库存状态等。 2. **LeetCode/牛客网** - 题平台提供真实面试题(如「第二高的薪水」「连续登录用户」)。 3. **Kaggle 公开数据集** - 用真实数据集练习复杂分析(如 COVID 数据、电影评分)。 --- 通过以上练习,你可以快速掌握工作中高频使用的 SQL 技能,应对数据查询、报表生成、业务分析等实际需求。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值