004 MySQL练习

选课系统中存在这样的三种表
学生表(Student): 学号(S#)、学生姓名(Sname)、学生年龄(Sage)、学生性别(Ssex);
课程表(Course):课程编号(C#)、课程名称(Cname)、教师编号(T#);
成绩表(SC):学号(S#)、课程编号(C#)、成绩(score);
教师表(Teacher):教师编号(T#)、教师名字(Tname)。
请用SQL完成以下需求
a查询"001"课程比"002"课程成绩高的所有学生的学号
b查询平均成绩大于60分的同学的学号和平均成绩
c查询所有同学的学号、姓名、选课数、总成绩
d查询没有学过"叶平"老师的同学的学号、姓名 e查询学过"001"并且也学过编号"002"课程的同学的学号、姓名

首先,我会针对每个需求分别给出SQL查询语句。

a) 查询"001"课程比"002"课程成绩高的所有学生的学号

SELECT s1.S#  
FROM SC s1, SC s2  
WHERE s1.S# = s2.S#  AND s1.C# = '001'  AND s2.C# = '002'  AND s1.score > s2.score;-- 当你执行这个 SQL 查询时,数据库管理系统(DBMS)会遵循一定的逻辑和执行顺序来处理查询。虽然实际的物理执行顺序可能因数据库的查询优化器而异,但我们可以按照逻辑执行顺序来解释这个查询。以下是该查询的逻辑执行顺序和讲解:-- FROM 子句:
-- 首先,DBMS 会确定要从哪些表中检索数据。在这个查询中,我们有两个表实例 SC s1 和 SC s2,它们实际上是同一个表 SC 的两个别名。使用别名允许我们在查询中多次引用同一个表,这在进行比较或连接表的不同行时非常有用。
-- WHERE 子句(包括连接条件):
-- 接下来,DBMS 会应用 WHERE 子句中的条件来过滤记录。这个查询的 WHERE 子句包含几个条件,它们将一起应用:
-- s1.S# = s2.S#:这是一个连接条件,用于将 s1 和 s2 两个表实例中的记录匹配起来。具体来说,它会找出那些在两个表实例中具有相同学号 (S#) 的记录。这实际上是一种自连接,因为我们正在比较同一个表的不同行。
-- s1.C# = '001' 和 s2.C# = '002':这两个条件分别过滤出 s1 中课程编号为 '001' 的记录和 s2 中课程编号为 '002' 的记录。
-- s1.score > s2.score:这个条件比较了匹配学号在两个不同课程中的分数,只选择那些在 '001' 课程中分数高于 '002' 课程的记录。
-- SELECT 子句:
-- 最后,一旦所有符合条件的记录都被确定,DBMS 就会根据 SELECT 子句中的指示选择并返回特定的列。在这个查询中,我们仅选择并返回了 s1.S#,即满足所有上述条件的学生的学号。
-- 总结来说,这个查询的逻辑是找出那些在 '001' 课程中得分高于 '002' 课程的所有学生的学号。它通过比较同一个学生(由学号 S# 标识)在两门不同课程中的分数来实现这一点。这种查询在处理诸如成绩比较、趋势分析或识别特定表现模式的学生等任务时非常有用。

b) 查询平均成绩大于60分的同学的学号和平均成绩

SELECT S#, AVG(score) AS avg_score  
FROM SC  
GROUP BY S#  
HAVING AVG(score) > 60;

c) 查询所有同学的学号、姓名、选课数、总成绩

SELECT Student.S#, Student.Sname, COUNT(SC.C#) AS course_count, SUM(SC.score) AS total_score  
FROM Student  
LEFT JOIN SC ON Student.S# = SC.S#  
GROUP BY Student.S#, Student.Sname;

d) 查询没有学过"叶平"老师的同学的学号、姓名

SELECT Student.S#, Student.Sname  
FROM Student  
WHERE S# NOT IN (  SELECT DISTINCT SC.S#  FROM SC  JOIN Course ON SC.C# = Course.C#  JOIN Teacher ON Course.T# = Teacher.T#  WHERE Teacher.Tname = '叶平'  
);-- 这条SQL查询的目的是从Student表中选择那些没有选修过'叶平'老师课程的学生的学号和姓名。下面我将从执行顺序的角度详细解释这条查询。-- 查询解释
-- 内层子查询:
-- sql
-- SELECT DISTINCT SC.S#    
-- FROM SC    
-- JOIN Course ON SC.C# = Course.C#    
-- JOIN Teacher ON Course.T# = Teacher.T#    
-- WHERE Teacher.Tname = '叶平'
-- 这个子查询首先通过JOIN操作连接了三个表:SC(学生课程表)、Course(课程表)和Teacher(教师表)。连接条件是课程编号(C#)和教师编号(T#)。然后,它筛选出教师名字为'叶平'的课程所对应的学生编号(S#),并确保学生编号是唯一的(通过DISTINCT)。-- 外层查询:
-- sql
-- SELECT Student.S#, Student.Sname    
-- FROM Student    
-- WHERE S# NOT IN (子查询结果)
-- 外层查询从Student表中选择学号(S#)和姓名(Sname)。WHERE子句中的条件是,学生的学号不能出现在内层子查询的结果中。换句话说,这个查询选择了所有没有选修过'叶平'老师课程的学生。-- 执行顺序(逻辑上)
-- FROM 子句:首先确定查询的主体表,这里是Student表。
-- 内层子查询:在执行外层查询之前,数据库会先执行内层子查询。
-- JOIN操作:先连接SC、Course和Teacher三个表,基于课程编号和教师编号的匹配。
-- WHERE子句:从连接后的结果中筛选出教师名字为'叶平'的记录。
-- DISTINCT:确保返回的学生编号是唯一的。
-- WHERE 子句(外层查询):使用内层子查询的结果来过滤Student表中的记录。具体来说,它会排除那些学号出现在内层子查询结果中的学生。
-- SELECT 子句:最后,从经过过滤的Student表中选择学号和姓名。
-- 这条查询的逻辑执行顺序大致如上所述,但实际的物理执行顺序可能会因数据库的查询优化器而有所调整,以提高查询效率。不过,从逻辑上理解,这个顺序有助于我们更好地掌握查询的工作原理。

SELECT s.S#, s.Sname  
FROM Student s  
LEFT JOIN (  SELECT DISTINCT sc.S#  FROM SC sc  JOIN Course c ON sc.C# = c.C#  JOIN Teacher t ON c.T# = t.T#  WHERE t.Tname = '叶平'  
) AS taught_by_yeping ON s.S# = taught_by_yeping.S#  
WHERE taught_by_yeping.S# IS NULL;-- 在这个查询中,我们首先创建了一个子查询(别名为 taught_by_yeping),该子查询选出了所有学过"叶平"老师课程的学生的学号。然后,我们使用 LEFT JOIN 将这个子查询的结果连接到 Student 表上。最后,通过 WHERE 子句筛选出那些在子查询结果中没有对应学号的学生,即没有学过"叶平"老师课程的学生。-- 这种方法通常比使用 NOT IN 更高效,特别是在处理大量数据时,因为 LEFT JOIN 通常能够更好地利用数据库索引,从而减少查询的执行时间。-- 子查询执行:
-- 在执行主查询之前,MySQL会首先处理子查询部分。这个子查询用于创建一个临时表(在本查询中命名为taught_by_yeping),其中包含选修了'叶平'老师课程的学生的学号(S#)。-- sql
-- SELECT DISTINCT sc.S#    
-- FROM SC sc    
-- JOIN Course c ON sc.C# = c.C#    
-- JOIN Teacher t ON c.T# = t.T#    
-- WHERE t.Tname = '叶平'
-- 首先,SC表(别名sc)与Course表(别名c)通过课程编号(C#)进行连接。
-- 接着,连接后的结果与Teacher表(别名t)通过教师编号(T#)进行连接。
-- 然后,WHERE子句筛选出教师名字为'叶平'的记录。
-- 最后,使用DISTINCT关键字确保返回的学生学号(S#)是唯一的。
-- 这个子查询的结果集将作为一个临时表taught_by_yeping,包含所有选修了'叶平'老师课程的学生的学号。-- 主查询执行:
-- 在子查询执行完毕后,主查询开始执行。主查询的目的是从Student表中选择那些没有选修过'叶平'老师课程的学生的学号和姓名。-- sql
-- SELECT s.S#, s.Sname    
-- FROM Student s    
-- LEFT JOIN taught_by_yeping ON s.S# = taught_by_yeping.S#    
-- WHERE taught_by_yeping.S# IS NULL
-- 首先,Student表(别名s)与前面创建的临时表taught_by_yeping进行左连接(LEFT JOIN),连接条件是学生学号(S#)。
-- 左连接会返回Student表中的所有记录,以及与之匹配的taught_by_yeping表中的记录(如果有的话)。如果taught_by_yeping表中没有匹配的记录,则对应的字段将为NULL。
-- 接着,WHERE子句筛选出taught_by_yeping.S#为NULL的记录,即那些在taught_by_yeping临时表中没有匹配学号的学生,这表示他们没有选修过'叶平'老师的课程。
-- 最后,SELECT子句选择这些学生的学号(S#)和姓名(Sname)。
-- 总结来说,这个查询通过子查询找出选修了'叶平'老师课程的学生学号,然后通过左连接和筛选条件找出没有选修过这些课程的学生,最终返回他们的学号和姓名。

SELECT s.S#, s.Sname  
FROM Student s  
LEFT JOIN SC sc ON s.S# = sc.S#  
LEFT JOIN Course c ON sc.C# = c.C#  
LEFT JOIN Teacher t ON c.T# = t.T# AND t.Tname = '叶平'  
GROUP BY s.S#, s.Sname  
HAVING COUNT(DISTINCT t.T#) = 0;-- 在这个查询中:-- 我们首先对 Student 表进行左连接,通过 SC 表连接到 Course 表,再通过 Course 表连接到 Teacher 表。
-- 在连接 Teacher 表时,我们在 ON 子句中加入了条件 t.Tname = '叶平',这样只有当教师名字是'叶平'时,才会进行连接。
-- 使用 GROUP BY 对学生学号和姓名进行分组,因为我们想要得到每个学生的结果。
-- HAVING COUNT(DISTINCT t.T#) = 0 确保我们只选择那些没有与'叶平'老师相关联的记录的学生。如果一个学生与'叶平'老师有关联,那么 COUNT(DISTINCT t.T#) 的值会大于0。
-- 请注意,这种方法可能在性能上不如使用子查询的方法,特别是当数据库中的记录数量非常大时。在实际应用中,建议测试不同的查询方法,以确定哪种方法在您的特定数据库和数据量下最有效。-- 另外,如果数据库中存在大量数据,确保相关的字段(如学号、课程号和教师号)已经被正确地索引,以提高查询性能。

e) 查询学过"001"并且也学过编号"002"课程的同学的学号、姓名

SELECT Student.S#, Student.Sname  
FROM Student  
WHERE S# IN (  SELECT S# FROM SC WHERE C# = '001'  
) AND S# IN (  SELECT S# FROM SC WHERE C# = '002'  
);

或者使用EXISTS子句来实现:

SELECT s.S#, s.Sname  
FROM Student s  
WHERE EXISTS (SELECT 1 FROM SC WHERE S# = s.S# AND C# = '001')  AND EXISTS (SELECT 1 FROM SC WHERE S# = s.S# AND C# = '002');

请注意,这些查询假设数据库中的表和字段都严格遵循您提供的结构,并且所有的字段名和表名都是准确无误的。在实际应用中,您可能需要根据实际的数据库结构和命名来调整这些查询。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/21905.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【实用技巧】Unity的Transform组件实用技巧

使用Unity的Transform组件时,有一些技巧可以帮助你更高效地进行游戏开发: 局部与全局变换: transform.localPosition 和 transform.localRotation 允许你在父对象的局部坐标系中设置位置和旋转,这在处理复杂的层次结构时非常有用。…

四川汇聚荣聚荣科技有限公司评价怎么样?

四川汇聚荣聚荣科技有限公司评价如何?在科技日新月异的今天,四川汇聚荣聚荣科技有限公司作为业界的一员,其表现自然引起了广泛关注。那么,这家公司究竟如何呢?接下来,我们将从四个不同方面对其进行深入剖析。 一、技术实力 四川…

教务管理系统带万字文档基于springboot+vue的校务管理系统java项目

文章目录 教务管理系统一、项目演示二、项目介绍三、万字项目文档四、部分功能截图五、部分代码展示六、底部获取项目源码和万字论文参考(9.9¥带走) 教务管理系统 一、项目演示 校务管理系统 二、项目介绍 基于springbootvue的前后端分离教…

Leetcode:整数转罗马数字

题目链接:12. 整数转罗马数字 - 力扣(LeetCode) 普通版本(贪心) 条件分析:罗马数字由 7 个不同的单字母符号组成,每个符号对应一个具体的数值。此外,减法规则还给出了额外的 6 个复…

简单聊下服务器防病毒

在当今数字化时代,服务器作为数据存储、处理与传输的核心设备,其安全性显得尤为关键。服务器防病毒工作,不仅是保障企业信息安全的重要一环,更是维护用户数据隐私的关键举措。以下,我们将从多个方面,简单探…

Unity之XR Interaction Toolkit如何使用XRSocketInteractable组件

前言 在虚拟现实(VR)和增强现实(AR)开发中,交互性是提升用户体验的关键。Unity作为一个领先的游戏开发引擎,提供了多种工具支持VR/AR开发。Unity的OpenXR插件扩展了这一功能,提供了更强大和灵活的交互系统。其中一个非常有用的组件是XRSocketInteractable。本文将详细介…

串口控制小车和小车PWM调速

1.串口控制小车 1. 串口分文件编程进行代码整合,通过现象来改代码 2.接入蓝牙模块,通过蓝牙控制小车 3.添加点动控制,如果APP支持按下一直发数据,松开就停止发数据(蓝牙调试助手的自定义按键不能实现)&…

随笔-我在武汉一周了

做梦一样,已经来武汉一周了,回顾一下这几天,还真是有意思。 周一坐了四个小时的高铁到了武汉站,照着指示牌打了个出租车。司机大姐开得很快,瞅了眼,最快速度到了110,差点把我晃晕。一下车就感觉…

计算机视觉与模式识别实验2-2 SIFT特征提取与匹配

文章目录 🧡🧡实验流程🧡🧡SIFT算法原理总结:实现SIFT特征检测和匹配通过RANSAC 实现图片拼接更换其他图片再次测试效果(依次进行SIFT特征提取、RANSAC 拼接) 🧡🧡全部代…

旋转油封和骨架油封有什么区别?

在机械系统的密封解决方案中,旋转油封和骨架油封是两种常见的选择。每种类型都具有独特的功能和优势,适用于不同的应用。本文将深入探讨旋转油封和骨架油封的主要区别,提供见解,帮助您为您的需求选择合适的油封。 1、功能设计 旋…

nginx异常重启

宝塔定时任务上添加 定时任务, 每10分钟 执行一次, 用于判断 nginx 是否异常导致 所有访问都访问不了,如果是, 则 重启nginx 这里需要创建一个 127.0.0.1 的站点 用来判断nginx是否正常 #!/bin/bash# Nginx 正常运行的端口号 NG…

Java编程常见问题汇总一

系列文章目录 文章目录 系列文章目录前言一、字符串连接误用二、错误的使用StringBuffer三、测试字符串相等性四、数字转换成字符串五、利用不可变对象(Immutable) 前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分…

浅谈防勒索病毒的关键

主机加固能否做好防勒索病毒的工作,一直是网络安全领域的重要议题。随着信息技术的飞速发展,勒索病毒等网络威胁层出不穷,对企业和个人数据安全构成了严重威胁。因此,如何通过主机加固提升安全防护能力,防止勒索病毒的…

【微信小程序】小锦哥小程序工具 v2.3.8.0

# 简介 小锦哥小程序工具是一款可以对微信小程序进行解密或者反编译的工具,通过这款工具,可以对别人已经发布的小程序进行解密或者是反编译,然后查看源代码。对于网络安全人员来说,可以使用该工具进行安全审计,发现其…

[ubuntu][pcl]PCL can not be found on this machine

Ubuntu 20.04无法找到PCL,因为“sudo install libpcl-dev”安装后包含的目录不正确 操作系统: Ubuntu20.04 PCL信息: Package: libpcl-dev Version: 1.10.0dfsg-5ubuntu1 Priority: extra Section: universe/libdevel Source: pcl Origin: Ubuntu 由…

(函数)判断字符串元音字母(C语言)

一、运行结果&#xff1b; 二、源代码&#xff1b; # define _CRT_SECURE_NO_WARNINGS # include <stdio.h>//声明判断元音函数&#xff1b; void vowel(char a[100], char b[100]);int main() {//初始化变量值&#xff1b;char a[100] { 0 };char b[100] { 0 };//获取…

PR怎么剪辑短视频:成都鼎茂宏升文化传媒公司

PR怎么剪辑短视频&#xff1a;从入门到精通的剪辑技巧 在当今的媒体时代&#xff0c;短视频已经成为了人们日常生活中不可或缺的一部分。而要制作出高质量的短视频&#xff0c;熟练掌握一款强大的视频剪辑软件是必不可少的。在众多软件中&#xff0c;Adobe Premiere Pro&#…

【数据结构】图论——Prim算法和Kruskal算法

目录 Prim算法和Kruskal算法Prim算法的原理数据结构算法步骤解释算法实现代码示例 Kruskal 算法Kruskal算法的原理和步骤Kruskal算法的实现数据结构并查集操作Kruskal算法 Prim算法和Kruskal算法 文章: 【数据结构】图论&#xff08;图的储存方式&#xff0c;图的遍历算法DFS和…

Linux.用户

使用su - 切换用户 切换root时要输入密码&#xff0c;但是看不到 创建用户组 groupadd用户组名&#xff0c;用getent查看有哪些组 getent group 创建用户 在root身份中使用gentent passwd 可以查当前的用户信息 使用getent group查看有哪些组 使用chmod修改权限 快捷方法…

【算法速查】万字图解带你快速入门八大排序(下)

君兮_的个人主页 即使走的再远&#xff0c;也勿忘启程时的初心 C/C 游戏开发 Hello,米娜桑们&#xff0c;这里是君兮_&#xff0c;首先在这里祝大家中秋国庆双节同乐&#xff01;&#xff01;抓住假期的小尾巴&#xff0c;今天来把算法速查的八大排序的后续写完&#xff0c;当…