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

【数据库-复试】sql语句综合练习

作业题1:利用订货管理数据库中表数据,用SQL完成查询。


答案 

1. 检索在北京的供应商的名称

直接过滤

SELECT 供应商名 FROM 供应商 WHERE 地址 = '北京';  

2. 检索向供应商 S3 发过订购单的职工的职工号和仓库号

方式一:IN 子查询

SELECT 职工号, 仓库号  
FROM 职工  
WHERE 职工号 IN (SELECT 职工号 FROM 订购单 WHERE 供应商号 = 'S3');  

方式二:JOIN 关联

SELECT DISTINCT z.职工号, z.仓库号  
FROM 职工 z  
JOIN 订购单 d ON z.职工号 = d.职工号  
WHERE d.供应商号 = 'S3';  

3. 检索和职工 E1、E3 都有联系的北京供应商信息

(错题,有详解)

方式一:子查询 + GROUP BY

SELECT *  
FROM 供应商  
WHERE 地址 = '北京'  
  AND 供应商号 IN (  
    SELECT 供应商号  
    FROM 订购单  
    WHERE 职工号 IN ('E1', 'E3')  
    GROUP BY 供应商号  
    HAVING COUNT(DISTINCT 职工号) = 2  
);  

方式二:两次 JOIN

SELECT s.*  
FROM 供应商 s  
JOIN 订购单 d1 ON s.供应商号 = d1.供应商号 AND d1.职工号 = 'E1'  
JOIN 订购单 d2 ON s.供应商号 = d2.供应商号 AND d2.职工号 = 'E3'  
WHERE s.地址 = '北京';  

最简写法 (满足题意且最简洁)

SELECT * FROM 供应商  
WHERE 地址 = '北京'  
  AND 供应商号 IN (SELECT 供应商号 FROM 订购单 WHERE 职工号 = 'E1')  
  AND 供应商号 IN (SELECT 供应商号 FROM 订购单 WHERE 职工号 = 'E3');  

4. 检索向 S4 供应商发出订购单的仓库所在城市

方式一:多层子查询

SELECT DISTINCT 城市  
FROM 仓库  
WHERE 仓库号 IN (  
    SELECT 仓库号  
    FROM 职工  
    WHERE 职工号 IN (  
        SELECT 职工号 FROM 订购单 WHERE 供应商号 = 'S4'  
    )  
);  

方式二:JOIN 关联

SELECT DISTINCT 仓库.城市
FROM 仓库
JOIN 职工 ON 仓库.仓库号 = 职工.仓库号
JOIN 订购单 ON 职工.职工号 = 订购单.职工号
WHERE 订购单.供应商号 = 'S4';    

5. 检索工资多于 1230 元职工向北京供应商发的订购单号

方式一:子查询嵌套

SELECT 订购单号  
FROM 订购单  
WHERE 职工号 IN (SELECT 职工号 FROM 职工 WHERE 工资 > 1230)  
  AND 供应商号 IN (SELECT 供应商号 FROM 供应商 WHERE 地址 = '北京');  

方式二:JOIN 关联

SELECT d.订购单号  
FROM 订购单 d  
JOIN 职工 z ON d.职工号 = z.职工号 AND z.工资 > 1230  
JOIN 供应商 s ON d.供应商号 = s.供应商号 AND s.地址 = '北京';  

6. 检索所有仓库的平均面积

唯一标准写法

SELECT AVG(面积) AS 平均面积 FROM 仓库;  

7. 检索每个仓库中工资多于 1220 元的职工个数

标准写法

SELECT 仓库号, COUNT(职工号) AS 职工个数  
FROM 职工  
WHERE 工资 > 1220  
GROUP BY 仓库号;  

8. 检索工资低于本仓库平均工资的职工信息

(错题,有详解)

方式一:子查询 JOIN

SELECT t.*  
FROM 职工 t  
JOIN (  
    SELECT 仓库号, AVG(工资) AS avg_salary  
    FROM 职工  
    GROUP BY 仓库号  
) s ON t.仓库号 = s.仓库号  
WHERE t.工资 < s.avg_salary;  

方式二:窗口函数(需数据库支持,如 MySQL 8.0+)

SELECT 仓库号, 职工号, 工资  
FROM (  
    SELECT *, AVG(工资) OVER (PARTITION BY 仓库号) AS avg_salary  
    FROM 职工  
) t  
WHERE 工资 < avg_salary;  

 


作业2:设教学数据库 Education 有三个关系

- 学生关系 S(SNO,SNAME,AGE,SEX,SDEPT)

- 学习关系 SC(SNO,CNO,GRADE)

- 课程关系 C(CNO,CNAME,CDEPT,TNAME)

查询问题:

1. 检索计算机系的全体学生的学号,姓名和性别;

2. 检索学习课程号为 C2 的学生学号与姓名;

3. 检索选修课程名为“DS”的学生学号与姓名;

4. 检索选修课程号为 C2 或 C4 的学生学号;

5. 检索至少选修课程号为 C2 和 C4 的学生学号;

6. 检索不学 C2 课的学生姓名和年龄;

7. 检索学习全部课程的学生姓名;

8. 查询所学课程包含学生 S3 所学课程的学生学号。


答案

(1)检索计算机系的全体学生的学号,姓名和性别

方法一:简单 WHERE 子句筛选

SELECT SNO, SNAME, SEX
FROM S
WHERE SDEPT = '计算机系';

解释:直接从学生关系表 S 中,通过 WHERE 子句筛选出所属系别为 “计算机系” 的记录,然后选择学号 SNO、姓名 SNAME 和性别 SEX 列。

(2)检索学习课程号为 C2 的学生学号与姓名

方法一:通过 SC 表关联查询

SELECT S.SNO, S.SNAME
FROM S
JOIN SC ON S.SNO = SC.SNO
WHERE SC.CNO = 'C2';

方法二:子查询方式

SELECT SNO, SNAME
FROM S
WHERE SNO IN (
    SELECT SNO
    FROM SC
    WHERE CNO = 'C2'
);

(3)检索选修课程名为 “DS” 的学生学号与姓名

方法一:三表连接查询

SELECT S.SNO, S.SNAME
FROM S
JOIN SC ON S.SNO = SC.SNO
JOIN C ON SC.CNO = C.CNO
WHERE C.CNAME = 'DS';

方法二:嵌套子查询

SELECT SNO, SNAME
FROM S
WHERE SNO IN (
    SELECT SNO
    FROM SC
    WHERE CNO IN (
        SELECT CNO
        FROM C
        WHERE CNAME = 'DS'
    )
);

(4)检索选修课程号为 C2 或 C4 的学生学号

方法一:IN 操作符

SELECT DISTINCT SNO
FROM SC
WHERE CNO IN ('C2', 'C4');

从学习关系表 SC 中,使用 IN 操作符筛选出课程号为 C2 或者 C4 的记录,再通过 DISTINCT 去除重复的学号。

方法二:OR 逻辑表达式

SELECT DISTINCT SNO
FROM SC
WHERE CNO = 'C2' OR CNO = 'C4';

(5)检索至少选修课程号为 C2 和 C4 的学生学号

方法一:GROUP BY 和 HAVING 子句

SELECT SNO
FROM SC
WHERE CNO IN ('C2', 'C4')
GROUP BY SNO
HAVING COUNT(DISTINCT CNO) = 2;

解释:先通过 WHERE 子句筛选出课程号为 C2 或者 C4 的记录,然后按照学号 SNO 进行分组(GROUP BY),最后使用 HAVING 子句筛选出分组中不同课程号数量为 2 的学号,即表示该学生同时选修了 C2 和 C4 课程。

方法二:自连接方式(较复杂)

SELECT DISTINCT s1.SNO
FROM SC s1
JOIN SC s2 ON s1.SNO = s2.SNO
WHERE s1.CNO = 'C2' AND s2.CNO = 'C4';

解释:将学习关系表 SC 进行自连接(相当于把 SC 表当作两个不同的表 s1 和 s2 进行连接),连接条件是两个表中的学号相等。然后在连接后的结果中,筛选出 s1 表中课程号为 C2 且 s2 表中课程号为 C4 的记录,最后通过 DISTINCT 去除重复的学号。

(6)检索不学 C2 课的学生姓名和年龄

方法一:NOT IN 子查询

SELECT SNAME, AGE
FROM S
WHERE SNO NOT IN (
    SELECT SNO
    FROM SC
    WHERE CNO = 'C2'
);

方法二:NOT EXISTS 子查询

SELECT SNAME, AGE
FROM S s
WHERE NOT EXISTS (
    SELECT 1
    FROM SC sc
    WHERE sc.SNO = s.SNO AND sc.CNO = 'C2'
);

解释:对于学生关系表 S 中的每一条记录(用 s 表示),通过 NOT EXISTS 子查询去检查在学习关系表 SC 中是否不存在满足学号相等且课程号为 C2 的记录。如果不存在这样的记录,那么该学生就是没有学习 C2 课程的,将其姓名和年龄选出来。

(7)检索学习全部课程的学生姓名

(错题,看详解)

方法一:使用 NOT EXISTS 和双重子查询

SELECT SNAME
FROM S s
WHERE NOT EXISTS (
    SELECT 1
    FROM C c
    WHERE NOT EXISTS (
        SELECT 1
        FROM SC sc
        WHERE sc.SNO = s.SNO AND sc.CNO = c.CNO
    )
);

方法二:使用 COUNT 和分组(假设课程表中课程数量已知为 N )

SELECT SNAME
FROM S s
JOIN SC sc ON s.SNO = sc.SNO
GROUP BY s.SNO, s.SNAME
HAVING COUNT(DISTINCT sc.CNO) = N;

解释:先将学生关系表 S 和学习关系表 SC 基于学号连接,然后按照学生学号和姓名进行分组(GROUP BY),对于每个分组,统计不同课程号的数量,当数量等于课程总数 N 时,说明该学生学习了全部课程,将其姓名选出来。但这种方法需要提前知道课程总数,通用性稍差。

(8)查询所学课程包含学生 S3 所学课程的学生学号

使用 NOT EXISTS 子查询

SELECT DISTINCT SNO
FROM SC s1
WHERE NOT EXISTS (
    SELECT 1
    FROM SC s2
    WHERE s2.SNO = 'S3'
        AND NOT EXISTS (
            SELECT 1
            FROM SC s3
            WHERE s3.SNO = s1.SNO AND s3.CNO = s2.CNO
        )
);

解释:对于学习关系表 SC 中的每个学生(用 s1 表示),通过最外层 NOT EXISTS 子查询判断。中间层子查询针对学生 S3 选修的每门课程(用 s2 表示)。最内层子查询检查对于某个学生 s1 是否存在 S3 选修的某门课程,而该学生没有选修的情况。如果不存在这样的情况,即表示该学生所学课程包含了 S3 所学课程,将其学号通过 DISTINCT 选出来。

相关文章:

  • Mysql--日志(错误日志、二进制日志、查询日志、慢查询日志)
  • 使用 fn_dblog手动恢复误操作的 update(单列数值型数据恢复)
  • 用卡片笔记要改变写作习惯
  • (并查集 省份数量)leetcode 547
  • Sqladmin - FastAPI框架下一键生成管理后台
  • Git 钩子:特定操作脚本
  • 深入掌握Spring AOP:从原理到实战的完整指南
  • 在 Qt 中,不带参数或整形的参选的信号能够从 std::thread 发送成功,而带枚举离线的信号却发送失败
  • cocos creator 笔记-路边花草
  • java8循环解压zip文件---实现Excel文件数据追加
  • 慧通测控汽车智能座舱测试技术
  • k8s基础知识总结node+pod(上)
  • CSS语言的双向链表
  • 4、pytest常用插件
  • word中指定页面开始添加页码
  • Python(4)Python函数编程性能优化全指南:从基础语法到并发调优
  • Java设计模式之访问者模式
  • 计算机网络 - OSI 七层模型
  • 笔记:分享如何使用github静态页面搭建个人页面
  • 【2025】基于springboot+uniapp的企业培训打卡小程序设计与实现(源码、万字文档、图文修改、调试答疑)
  • 纽约市长称墨海军帆船撞桥已致2人死亡,撞桥前船只疑似失去动力
  • 光速晋级!2025年多哈世乒赛孙颖莎4比0战胜对手
  • 雅典卫城上空现“巨鞋”形状无人机群,希腊下令彻查
  • 幼儿园教师拍打孩子额头,新疆库尔勒教育局:涉事教师已被辞退
  • 中期选举后第三势力成“莎拉弹劾案”关键,菲律宾权斗更趋复杂激烈
  • 李成钢:近期个别经济体实施所谓“对等关税”,严重违反世贸组织规则