Java学习--MySql练习-子查询

这篇博客介绍了在Java学习中使用MySQL进行子查询的实践,涵盖了创建学生、教师、课程和成绩表,并通过一系列查询题目展示子查询的应用,如查询特定分数段学生、未选全课程的学生、课程选修人数等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、创建相应表格

1、创建一张学生(Student)表,属性如下:

学生编号 SID 整数 主键 自增从1001开始
学生姓名 SNAME 字符串 长度为20 不为空
学生年龄 BIRTHDAY 日期 
学生性别 SEX 字符串 长度为1
create table if not exists student(
	sid int primary key auto_increment,
	sname varchar(20) not null,
	birthday date,
	sex char(1)
) auto_increment=1001;

插入如下数据:

+------+-------+---------------------+------+
| sid  | sname | birthday            | sex  |
+------+-------+---------------------+------+
| 1001 | 张三  | 1990-10-10 00:00:00 ||
| 1002 | 李四  | 1981-10-10 00:00:00 ||
| 1003 | 王五  | 1981-11-10 00:00:00 ||
| 1004 | 赵六  | 1988-10-10 00:00:00 ||
| 1005 | 孙七  | 1989-01-10 00:00:00 ||
| 1006 | 周八  | 1990-10-10 00:00:00 ||
| 1007 | 张三  | 1990-06-10 00:00:00 ||
+------+-------+---------------------+------+

2、创建教师表(Teacher)

教师编号 TID 整数 主键 自增
教师姓名 TNAME 字符串 长度为20 不为空
create table if not exists teacher(
	tid int primary key auto_increment,
	tname varchar(20) not null
);

插入如下数据:

+-----+--------+
| tid | tname  |
+-----+--------+
|   1 | 叶平   |
|   2 | 王老师 |
|   3 | 张老师 |
|   4 | 李老师 |
|   5 | 孙老师 |
+-----+--------+

3、创建一张课程表(Course)

课程编号 CID 整数 主键 自增
课程名称 CNAME 字符串 长度为20 不为空
教师编号 TID 必须与教师表中的TID相符,不能为空
create table if not exists course(
	cid int primary key auto_increment,
	cname varchar(20) not null,
	tid int not null,
	foreign key(tid) references teacher(tid)	
);

插入如下数据:

+-----+----------+-----+
| cid | cname    | tid |
+-----+----------+-----+
|   1 | 企业管理 |   1 |
|   2 | 马克思   |   2 |
|   3 | UML      |   3 |
|   4 | 数据库   |   4 |
|   5 | 英语     |   5 |
|   6 | 语文     |   1 |
|   7 | 数学     |   2 |
+-----+----------+-----+

4、创建成绩表(SC)

学生编号 SID  必须与学生表中的学生编号相符,不为空
课程编号 CID  必须与课程表中的课程编号相符,不为空
成绩 SCORE 整数 不为空
课程编号与学生编号应该联合唯一
create table if not exists sc(
	sid int not null,
	cid int not null,	
	score tinyint not null,
	foreign key(cid) references course(cid),
	foreign key(sid) references student(sid),
	primary key(cid,sid)
);

插入如下数据:

+------+-----+-------+
| sid  | cid | score |
+------+-----+-------+
| 1001 |   1 |    50 |
| 1002 |   1 |    90 |
| 1003 |   1 |    59 |
| 1004 |   1 |    80 |
| 1005 |   1 |    50 |
| 1006 |   1 |    60 |
| 1007 |   1 |   100 |
| 1001 |   2 |    70 |
| 1003 |   2 |    70 |
| 1004 |   2 |    70 |
| 1005 |   2 |    50 |
| 1001 |   3 |    80 |
| 1005 |   3 |   100 |
| 1001 |   4 |    90 |
| 1002 |   4 |    55 |
| 1005 |   4 |    30 |
| 1007 |   4 |    58 |
| 1001 |   5 |    80 |
| 1001 |   6 |    80 |
| 1002 |   6 |    90 |
| 1007 |   6 |    90 |
| 1001 |   7 |   100 |
| 1002 |   7 |    80 |
| 1007 |   7 |    80 |
+------+-----+-------+

二、子查询题目

1、查询所有课程成绩都小于等于60分的同学的学号、姓名

(select sid from sc group by sid having max(score)<=60) a 

用表连接
select * from student b 
    inner join 
    (select sid from sc group by sid having max(score)<=60) a 
    on b.sid=a.sid;in
select * from student
    where sid 
    in (select sid from sc group by sid having max(score)<=60);

用取反的做法
select sid from sc where score > 60;
select * from student 
    where sid 
    not in(select sid from sc where score > 60);

查询结果如下:

+------+-------+---------------------+------+
| sid  | sname | birthday            | sex  |
+------+-------+---------------------+------+
| 1006 | 周八  | 1990-10-10 00:00:00 ||
+------+-------+---------------------+------+

2、查询没有学全所有课的同学的学号、姓名

select count(*) from course; 求得总课程数

求得没有学全总课程数的sid
(select sid from sc group by sid having count(*)<(select count(*) from course)) a 

select * from 
    (select sid from sc group by sid having count(*)<(select count(*) from course)) a 
    inner join student b on a.sid=b.sid;

查询结果如下:

+------+------+-------+---------------------+------+
| sid  | sid  | sname | birthday            | sex  |
+------+------+-------+---------------------+------+
| 1002 | 1002 | 李四  | 1981-10-10 00:00:00 ||
| 1003 | 1003 | 王五  | 1981-11-10 00:00:00 ||
| 1004 | 1004 | 赵六  | 1988-10-10 00:00:00 ||
| 1005 | 1005 | 孙七  | 1989-01-10 00:00:00 ||
| 1006 | 1006 | 周八  | 1990-10-10 00:00:00 ||
| 1007 | 1007 | 张三  | 1990-06-10 00:00:00 ||
+------+------+-------+---------------------+------+

3、查询每门课程选修人数,格式为课程名称,人数

先统计个数,再连接课程表
(select cid, count(*) from sc group by cid) a

select totalcount,cname from 
    (select cid, count(*) totalcount from sc group by cid) a
    inner join course b on a.cid=b.cid;

先连接课程表,再统计个数
select a.cid,cname,count(*) 
    from sc a 
    inner join course b 
    on a.cid=b.cid group by a.cid, cname;

查询结果如下:

+-----+----------+----------+
| cid | cname    | count(*) |
+-----+----------+----------+
|   1 | 企业管理 |        7 |
|   2 | 马克思   |        4 |
|   3 | UML      |        2 |
|   4 | 数据库   |        4 |
|   5 | 英语     |        1 |
|   6 | 语文     |        3 |
|   7 | 数学     |        3 |
+-----+----------+----------+

4、查询全部学生都选修的课程的课程号和课程名

select * from 
    (select sid from sc group by sid having count(*)=(select count(*) from course)) a 
    inner join student b on a.sid=b.sid;

查询结果如下:

+------+------+-------+---------------------+------+
| sid  | sid  | sname | birthday            | sex  |
+------+------+-------+---------------------+------+
| 1001 | 1001 | 张三  | 1990-10-10 00:00:00 ||
+------+------+-------+---------------------+------+

5、查询两门以上不及格课程的同学的学号及其平均成绩

select sid from sc 
    where score<60 group by sid having count(*)>=2; 

select sid,avg(score) from sc where sid in 
    (select sid from sc where score<60 group by sid having count(*)>=2) 
    group by sid;

查询结果如下:

+------+------------+
| sid  | avg(score) |
+------+------------+
| 1005 |    57.5000 |
+------+------------+

6、查询2号课程成绩比1号课程成绩低的学生的学号、姓名

(select sid,cid,score from sc where cid=1) a 表a:选1号课程学生的学号、成绩
(select sid,cid,score from sc where cid=2) b 表b:选2号课程学生的学号、成绩

(select a.sid from (select sid,cid,score from sc where cid=1)a inner join 
(select sid,cid,score from sc where cid=2)b on a.sid=b.sid and a.score>b.score)c

select * from 
    (select a.sid from (select sid,cid,score from sc where cid=1) a 
    inner join (select sid,cid,score from sc where cid=2) b 
        on a.sid=b.sid and a.score>b.score) c 
    inner join student d where c.sid=d.sid;
select d.sid,d.sname from 
    (select a.sid from (select sid,cid,score from sc where cid=1) a 
    inner join (select sid,cid,score from sc where cid=2) b 
        on a.sid=b.sid and a.score>b.score) c 
    inner join student d where c.sid=d.sid;

查询结果如下:

+------+-------+
| sid  | sname |
+------+-------+
| 1004 | 赵六  |
+------+-------+

7、查询学过1号课程并且也学过编号2号课程的同学的学号、姓名

select * from 
    (select a.sid from (select sid,cid,score from sc where cid=1) a 
    inner join (select sid,cid,score from sc where cid=2)b on a.sid=b.sid)c 
    inner join student d where c.sid=d.sid;
select d.sid,d.sname from     
    (select a.sid from (select sid,cid,score from sc where cid=1) a     
    inner join (select sid,cid,score from sc where cid=2)bon a.sid=b.sid)c     
    inner join student d where c.sid=d.sid;

查询结果如下:

+------+-------+
| sid  | sname |
+------+-------+
| 1001 | 张三  |
| 1003 | 王五  |
| 1004 | 赵六  |
| 1005 | 孙七  |
+------+-------+

8、查询没学过“叶平”老师课的同学的学号、姓名

 找到的是叶平教过的学生的sid
select sid from teacher a 
    inner join course b on a.tid=b.tid 
    inner join sc c on b.cid=c.cid where a.tname='叶平';

再利用not in 排除这些sid
select * from student 
    where sid not in 
    (select sid from teacher a 
        inner join course b on a.tid=b.tid 
        inner join sc c on b.cid=c.cid 
        where a.tname='叶平');

查询结果如下:

Empty set (0.10 sec)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值