【面试题】MYSQL查询每个学生所选择的课程和选择了所有课程的学生

在这里插入图片描述

在这里插入图片描述

– 创建学生表
CREATE TABLE student (
Sid INT PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(20)
);

  • 创建课程表
    CREATE TABLE course(
    Cid INT PRIMARY KEY AUTO_INCREMENT,
    cname VARCHAR(20)
    );
    – 创建学生表和课程表的三方外键关联表
    CREATE TABLE stu_course(
    sid INT,
    cid INT,
    FOREIGN KEY(sid)REFERENCES student (sid),
    FOREIGN KEY(cid)REFERENCES course(cid)
    );
    – 向学生表中插入数据
    INSERT INTO student VALUES(NULL,‘张三’),(NULL,‘李思思’),(NULL,‘李虎’);
    – 向课程表中插入数据
    INSERT INTO course (cname)VALUES (’ JAVA’),(’ ANDROID’), (’ IOS’), (’ PHP’), (’ C++');
    –向三方外键关联表中插入数据、
    INSERT INTO stu_course (sid, cid) VALUES (1, 1);
    INSERT INTO stu_course (sid, cid) VALUES (1, 3);
    INSERT INTO stu_course (sid, cid) VALUES (1, 5);
    INSERT INTO stu_course (sid, cid) VALUES (1, 2);
    INSERT INTO stu_course (sid, cid) VALUES (1, 4);
    INSERT INTO stu_course (sid, cid) VALUES (2, 1);
    INSERT INTO stu_course (sid, cid) VALUES (2, 2);
    INSERT INTO stu_course (sid, cid) VALUES (3, 2);
    INSERT INTO stu_course (sid, cid) VALUES (3, 3);
    INSERT INTO stu_course (sid, cid) VALUES (3, 5);

问题:
(1)查询每个学生所选择的课程(5分)

(2)选择了所有课程的学生(6分)

解决:

1、先观察表数据
在这里插入图片描述
(1)查询每个学生所选择的课程(5分)

SELECT s.sname AS 学生姓名, c.cname AS 所选课程
FROM student s
JOIN stu_course sc ON s.Sid = sc.sid
JOIN course c ON sc.cid = c.Cid;

在这里插入图片描述
注释:

– 选择每个学生所选的课程,通过连接学生表、三方外键关联表和课程表
SELECT s.sname AS 学生姓名, c.cname AS 所选课程

FROM student s – 从学生表中选择数据,将其别名为s

JOIN stu_course sc ON s.Sid =sc.sid – 将学生表和三方外键关联表连接,使用学生ID进行匹配

JOIN course c ON sc.cid = c.Cid; – 将课程表和三方外键关联表连接,使用课程ID进行匹配

(2)选择了所有课程的学生(6分)

SELECT s.sname AS 学生姓名
FROM student s
WHERE NOT EXISTS (
    SELECT c.Cid
    FROM course c
    WHERE NOT EXISTS (
        SELECT sc.cid
        FROM stu_course sc
        WHERE sc.cid = c.Cid AND sc.sid = s.Sid
    )
);

在这里插入图片描述
注释:

SELECT s.sname AS 学生姓名  -- 选择学生表中的学生姓名
FROM student s  -- 从学生表中选择数据,将其别名为s
WHERE NOT EXISTS (  -- 判断以下子查询是否为空集合
    SELECT c.Cid  -- 选择课程表中的课程ID
    FROM course c  -- 从课程表中选择数据,将其别名为c
    WHERE NOT EXISTS (  -- 判断以下子查询是否为空集合
        SELECT sc.cid  -- 选择三方外键关联表中的课程ID
        FROM stu_course sc  -- 从三方外键关联表中选择数据,将其别名为sc
        WHERE sc.cid = c.Cid AND sc.sid = s.Sid  -- 匹配学生ID和课程ID
    )
);

第二种解法:推荐

SELECT 
    sc.sid AS StudentID,
    s.sname AS StudentName
FROM 
    stu_course sc
JOIN 
    student s ON sc.sid = s.sid
GROUP BY 
    sc.sid
HAVING 
    COUNT(sc.cid) = (SELECT COUNT(*) FROM course);

在这里插入图片描述
注释:
这个查询语句首先通过stu_course关联表和student表连接来获取所有选课的学生。然后,通过GROUP BY对学生ID进行分组,并使用HAVING子句来确保只有选择了与course表中课程总数一样多的课程的学生被选出。子查询(SELECT COUNT(*) FROM course)用于获取课程的总数。

第三种解法:

SELECT 
    s.sname AS StudentName
FROM 
    student s
JOIN 
    stu_course sc ON s.sid = sc.sid
GROUP BY 
    s.sid, s.sname
HAVING 
    COUNT(sc.cid) = (SELECT COUNT(DISTINCT cid) FROM course);

注释:
这个查询语句的逻辑是:
从student表中选择学生姓名。
通过JOIN操作与stu_course表关联,以获取每个学生所选的课程。
使用GROUP BY对学生ID和姓名进行分组,因为我们需要按学生来筛选。
使用HAVING子句来筛选出那些选课数量等于总课程数量的学生。这里使用子查询(SELECT COUNT(DISTINCT cid) FROM course)来获取course表中不同课程的总数。
请注意,COUNT(DISTINCT cid)确保我们统计的是不同的课程数量,而不是课程的总记录数(如果有重复的课程ID则需要去重)。

第四种解法:

SELECT 
    s.sname AS StudentName
FROM 
    student s
WHERE 
    NOT EXISTS (
        SELECT 1
        FROM course c
        WHERE NOT EXISTS (
            SELECT 1
            FROM stu_course sc
            WHERE sc.sid = s.sid AND sc.cid = c.cid
        )
    );

注释:

  1. student表中选择学生姓名。
  2. 对于每个学生,使用NOT EXISTS子句来检查是否存在至少一门课程,该学生没有选。
  3. 内层的NOT EXISTS子句检查course表中的每一门课程,看是否在stu_course表中与当前学生的ID关联。
  4. 如果对于course表中的任何课程,都没有找到与当前学生ID关联的记录,那么这个学生就没有选择所有课程,因此这个子句的结果为TRUE,外层的SELECT将排除这个学生。
  5. 只有当所有课程都被至少选了一次时,NOT EXISTS子句的结果才为FALSE,这样学生才会被包括在外层查询的结果中。

这种方法使用了逻辑上的否定,通过排除那些没有选择所有课程的学生来找出那些选择了所有课程的学生。

  • 12
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MySQL 是一款广受欢迎的开源关系型数据库管理系统(RDBMS),由瑞典MySQL AB公司开发,现隶属于美国甲骨文公司(Oracle)。自1998年首次发布以来,MySQL以其卓越的性能、可靠性和可扩展性,成为全球范围内Web应用程序、企业级解决方案以及其他各种数据处理场景的首数据库平台之一。 以下是对MySQL数据库的详细介绍: 核心特性与优势 开源与跨平台 MySQL遵循GPL开源协议,这意味着任何人都可以免费下载、使用和修改其源代码。这种开放性促进了广泛的社区支持和第三方插件、工具的发展。此外,MySQL支持多种操作系统,包括Windows、Linux、macOS、Solaris等,确保了其在不同环境下的兼容性和部署灵活性。 关系型模型与SQL支持 MySQL基于关系型数据库模型,数据以表格形式组织,并通过预定义的键(如主键、外键)在表之间建立关联。它完全支持结构化查询语言(SQL),允许用户进行数据查询、插入、更新、删除、创建和管理数据库结构等操作。SQL标准的广泛支持使得MySQL易于学习,且与其他关系型数据库系统有良好的互操作性。 存储引擎 MySQL支持多种存储引擎,如InnoDB、MyISAM、MEMORY等,每种引擎都有特定的优势和适用场景。例如,InnoDB提供事务安全、行级锁定和外键约束,适合处理高并发事务性的应用;MyISAM则更侧重于读取密集型操作,提供全文索引支持,适用于读多写少的场景。这种多引擎架构使得MySQL能够适应不同业务需求,提供高度定制化的存储解决方案。 性能与可扩展性 MySQL通过高效的缓存机制、查询优化器以及对硬件资源的有效利用,保证了在高负载情况下的稳定性和快速响应。它支持水平扩展(如通过分片、复制等技术)和垂直扩展(如增加硬件资源),以应对大规模数据存储和高并发访问的需求。 安全性与管理工具 MySQL提供了一系列安全措施,如用户账户管理、访问权限控制、SSL/TLS加密连接、审计日志等功能,确保数据的安全性和合规性。同时,MySQL附带了一系列管理工具,如MySQL Server、MySQL Workbench、MySQL Shell等,便于用户进行数据库配置、监控、备份、恢复、迁移等工作。 社区与生态系统
仅实现了基本增删改查功能。另一个是使用Tkinter实现的简单计算器 MySQL 是一款广受欢迎的开源关系型数据库管理系统(RDBMS),由瑞典MySQL AB公司开发,现隶属于美国甲骨文公司(Oracle)。自1998年首次发布以来,MySQL以其卓越的性能、可靠性和可扩展性,成为全球范围内Web应用程序、企业级解决方案以及其他各种数据处理场景的首数据库平台之一。 以下是对MySQL数据库的详细介绍: 核心特性与优势 开源与跨平台 MySQL遵循GPL开源协议,这意味着任何人都可以免费下载、使用和修改其源代码。这种开放性促进了广泛的社区支持和第三方插件、工具的发展。此外,MySQL支持多种操作系统,包括Windows、Linux、macOS、Solaris等,确保了其在不同环境下的兼容性和部署灵活性。 关系型模型与SQL支持 MySQL基于关系型数据库模型,数据以表格形式组织,并通过预定义的键(如主键、外键)在表之间建立关联。它完全支持结构化查询语言(SQL),允许用户进行数据查询、插入、更新、删除、创建和管理数据库结构等操作。SQL标准的广泛支持使得MySQL易于学习,且与其他关系型数据库系统有良好的互操作性。 存储引擎 MySQL支持多种存储引擎,如InnoDB、MyISAM、MEMORY等,每种引擎都有特定的优势和适用场景。例如,InnoDB提供事务安全、行级锁定和外键约束,适合处理高并发事务性的应用;MyISAM则更侧重于读取密集型操作,提供全文索引支持,适用于读多写少的场景。这种多引擎架构使得MySQL能够适应不同业务需求,提供高度定制化的存储解决方案。 性能与可扩展性 MySQL通过高效的缓存机制、查询优化器以及对硬件资源的有效利用,保证了在高负载情况下的稳定性和快速响应。它支持水平扩展(如通过分片、复制等技术)和垂直扩展(如增加硬件资源),以应对大规模数据存储和高并发访问的需求。 安全性与管理工具 MySQL提供了一系列安全措施,如用户账户管理、访问权限控制、SSL/TLS加密连接、审计日志等功能,确保数据的安全性和合规性。同时,MySQL附带了一系列管理工具,如MySQL Server、MySQL Workbench、MySQL Shell等,便于用户进行数据库配置、监控、备份、恢复、迁移等工作。 社区与生态系统

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值