当前位置: 首页 > news >正文

高阶子查询题目精炼

数据库子查询题集(10题)

以下题目基于典型的“学生-课程-成绩”数据库模式,并引入复杂场景、性能陷阱及高级SQL特性,旨在深入考察对子查询执行原理、优化策略及逻辑转换的理解。

题号题目描述考察核心
1多层嵌套与聚合:查询“平均成绩高于全校学生平均成绩,且其最高单科成绩高于该科目平均分20分以上”的学生的学号和姓名。多层聚合子查询、HAVING子句中的复杂条件。
2相关子查询与极值:找出每门课程中,成绩不是最高也不是最低的学生名单(即排除每门课的最高分和最低分获得者)。相关子查询、NOT IN与极值查询(MAX,MIN)的结合。
3EXISTS 与 三表关联:查询从未选修过“张老师”所授课程,但选修过所有“李老师”所授课程的学生信息。EXISTS,NOT EXISTS与全称量词的逻辑转换(通过双重否定或计数实现)。
4ALL/ANY 与除法运算:查询选修了计算机系开设的全部课程的学生学号。使用NOT EXISTS模拟关系代数中的“除法”运算。
5标量子查询与更新:将每位学生的总成绩更新到学生表的一个新增字段total_score中,要求使用单条UPDATE语句配合标量子查询完成。UPDATESET子句中使用相关标量子查询。
6FROM 子句中的子查询与窗口函数:查询每个班级中,总成绩排名前10%的学生。要求使用FROM子句中的子查询先计算排名和百分比,再筛选。子查询生成派生表(Derived Table)并与窗口函数(RANK(),NTILE())结合。
7条件子查询与 CASE 表达式:生成一份报告,列出所有学生。对于每个学生,如果其有任何一门课成绩低于60分,则显示“有不及格”;如果所有成绩都在85分以上,则显示“优秀”;否则显示“普通”。SELECT子句和CASE WHEN中使用EXISTS和聚合子查询。
8横向连接 (LATERAL JOIN) 问题:对于每个学生,找出其成绩最高的两门课程的名称和分数。使用LATERAL子查询(或特定数据库的等效语法)实现行间关联。
9集合运算与子查询性能:查询本学期有成绩记录,但上学年没有任何成绩记录的学生。分别用NOT INNOT EXISTSLEFT JOIN...IS NULL三种方法实现,并分析其执行计划可能存在的差异。不同逻辑写法对数据库优化器(如He3DB的子连接上拉)的影响及性能对比。
10递归子查询(CTE):给定一个“员工-经理”表(employee_id, manager_id, salary),找出每个员工的所有间接下属(不限层级)中,薪资最高的那位员工的薪资。使用递归公共表表达式(CTE)遍历树形结构,并在外层查询中进行聚合。

部分难题的参考解答与深度解析

题目 2:相关子查询与极值

-- 方法:找出每门课成绩既不是最大值也不是最小值的学生 SELECT DISTINCT s.student_id, s.name, c.course_name, sc.score FROM student s JOIN score sc ON s.student_id = sc.student_id JOIN course c ON sc.course_id = c.course_id WHERE sc.score <> ( SELECT MAX(score) FROM score sc2 WHERE sc2.course_id = sc.course_id -- 相关子查询,找当前课程最高分 ) AND sc.score <> ( SELECT MIN(score) FROM score sc3 WHERE sc3.course_id = sc.course_id -- 相关子查询,找当前课程最低分 );

解析:此查询为每个成绩行执行了两次相关子查询以获取当前课程的极值,可能产生性能问题。优化器可能尝试将其转换为JOIN,但相关性子查询限制了上拉优化。

题目 4:ALL/ANY 与除法运算(使用 NOT EXISTS 实现)

-- 查询选修了计算机系全部课程的学生 SELECT s.student_id FROM student s WHERE NOT EXISTS ( -- 找出计算机系开设的、该学生没选的课程 SELECT c.course_id FROM course c WHERE c.dept = '计算机系' AND NOT EXISTS ( SELECT 1 FROM score sc WHERE sc.student_id = s.student_id AND sc.course_id = c.course_id ) );

解析:这是经典的关系除法问题的NOT EXISTS解法。它通过双重否定(“不存在一门计算机系的课是他没选的”)来表达全称量词。外层查询遍历学生,内层第一重NOT EXISTS检查是否有一门计算机系的课不在该学生的选课列表中(由最内层NOT EXISTS判断)。这种嵌套相关子查询是优化器的重点优化对象,在He3DB等数据库中可能会被重写为更高效的semijoinantijoin

题目 9:集合运算与性能分析

-- 方法1: NOT IN (需注意NULL值问题) SELECT student_id FROM score WHERE term = '2024-春' AND student_id NOT IN ( SELECT student_id FROM score WHERE term = '2023-秋' ); -- 方法2: NOT EXISTS (通常更优) SELECT s.student_id FROM score s WHERE s.term = '2024-春' AND NOT EXISTS ( SELECT 1 FROM score s2 WHERE s2.term = '2023-秋' AND s2.student_id = s.student_id ); -- 方法3: LEFT JOIN ... IS NULL SELECT DISTINCT s.student_id FROM score s LEFT JOIN score s_prev ON s.student_id = s_prev.student_id AND s_prev.term = '2023-秋' WHERE s.term = '2024-春' AND s_prev.student_id IS NULL;

性能分析

  • NOT IN:如果子查询返回结果集包含NULL值,则整个NOT IN条件可能返回UNKNOWN(即无结果),这是逻辑陷阱。性能上,数据库可能将其实现为Hash Anti Join
  • NOT EXISTS:是表达此逻辑最清晰和安全的方式,通常能利用关联字段的索引。现代数据库优化器(如MySQL 8.0+、He3DB)擅长将NOT EXISTS重写为高效的antijoin
  • LEFT JOIN...IS NULL:这是一种更“过程化”的写法,明确指示数据库先进行连接操作。在拥有良好统计信息时,优化器可能生成与NOT EXISTS相似的执行计划。但在复杂情况下,它可能比NOT EXISTS产生更大的中间结果集。

核心优化点:数据库优化器在查询重写阶段,会尝试将子查询(特别是EXISTS/IN类)“上拉”为JOIN,以减少嵌套迭代。例如,He3DB会将满足条件的EXISTS_SUBLINK转换为semijoin,将NOT EXISTS转换为antijoin,从而可以利用高效的连接算法(如Hash Join)和并行执行。能否成功上拉取决于子查询是否“相关”(引用外层列)以及其复杂程度。

题目 10:递归子查询(CTE)

WITH RECURSIVE SubordinateTree AS ( -- 锚点:直接下属 SELECT employee_id, manager_id, salary FROM employee UNION ALL -- 递归:间接下属 SELECT st.employee_id, e.manager_id, e.salary FROM SubordinateTree st JOIN employee e ON st.manager_id = e.employee_id ) SELECT emp.employee_id, (SELECT MAX(salary) FROM SubordinateTree st WHERE st.employee_id = emp.employee_id) as max_subordinate_salary FROM employee emp;

解析:此CTE先递归构建出每个员工的所有下属关系(包括间接)。外层查询通过一个标量子查询,从递归结果中找出每个员工下属的最高薪资。递归CTE是解决层次查询的强有力工具,但其性能依赖于递归深度和表的索引情况。


参考来源

  • 大云海山数据库(He3DB) 内核分析-子查询优化
  • PTA沈师数据库原理——DB(10)_SQL实验题
  • MySQL查询之子查询详解:从执行原理到深度优化
  • 数据库子查询
  • 数据库子查询
  • 数据仓库原理与实践课程指南
http://www.cnnetsun.cn/news/2636484.html

相关文章:

  • FileZilla Server安装配置避坑全记录:从用户权限到防火墙设置,一次搞定
  • Windows驱动管理终极指南:DriverStore Explorer完全解析与实用技巧
  • Arduino物联网入门:基于MQTT协议实现传感器数据稳定发布
  • 别再复制粘贴了!手把手教你用Angular+SpringBoot定制医院电子病历模板(附汉密尔顿抑郁量表实战)
  • Adams虚拟样机避坑指南:行星齿轮仿真中‘齿轮副创建失败’的3个常见原因及解决方法
  • DIY电吉他制作指南:从电磁感应原理到动手实践
  • CCPD车牌数据集转YOLOv5格式的完整脚本与避坑指南(附Python代码)
  • 5分钟从零开始:用RVC-WebUI实现专业级AI语音克隆转换
  • 告别硬核代码!在UE4里用UMG和材质轻松实现CSS级圆角按钮(附完整材质蓝图)
  • 技术深度解析:Vue3+Vite低代码平台架构与可视化编辑实现路径
  • 基于STM32的模型火箭飞控系统设计:从硬件选型到软件实现
  • Python多线程编程实战:从GIL原理到树莓派传感器数据采集
  • 微信网页版终极解决方案:3分钟让微信在浏览器中重新可用
  • 查询rownum伪列引起的sql性能问题分析
  • German-Sentiment-BERT模型架构深度解析:从BERT到情感分类的终极指南
  • 解锁个人数据价值:微信聊天记录本地化管理的完整解决方案
  • ESP32多通道遥控系统:I-Bus协议解析与电机驱动实战
  • 如何60秒快速下载Steam创意工坊动态壁纸:Flutter工具的终极指南
  • FastAdmin后台自定义页面保姆级教程:从控制器到菜单,5分钟搞定一个Hello World
  • 基于OpenCV与Arduino的手势控制机械臂:从视觉追踪到实时运动
  • 电子课本下载神器:3步极速获取国家平台教材的智能方案
  • Onekey Steam Depot Manifest下载器:终极游戏解锁工具完全指南
  • ChatGPT能力升级:从聊天机器人到智能体,解锁企业级AI应用新范式
  • 别再只盯着串联机械臂了!5自由度并联机械臂的搬运应用实战,精度与刚性实测
  • 终极指南:如何快速实现Windows微信QQ消息永久保存的完整教程
  • 区块链+AGI:用去中心化治理构建可信的超级智能未来
  • 罗科的蛇怪:拆解AI思想实验的逻辑漏洞与心理影响
  • 10分钟掌握:国家中小学智慧教育平台电子课本高效下载全攻略
  • 告别脆弱的单体应用,用多智能体网络构建稳定的生产力工具
  • WinPython终极指南:5分钟打造Windows便携Python环境,告别环境配置烦恼