MySQL经典题目--初学者练手入门,包含解题答案及解题思路

数据表介绍

      --题目设计四张表,学生表,课程表,教师表,成绩表

--1.学生表

Student(SId,Sname,Sage,Ssex)

--SId 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别

--2.课程表

Course(CId,Cname,TId)

--CId 课程编号,Cname 课程名称,TId 教师编号

--3.教师表

Teacher(TId,Tname)

--TId 教师编号,Tname 教师姓名

--4.成绩表

SC(SId,CId,score)

--SId 学生编号,CId 课程编号,score 分数

      --载入数据

学生表 Student

create table Student(SId varchar(10),Sname varchar(10),Sage datetime,Ssex varchar(10));

insert into Student values('01' , '赵雷' , '1990-01-01' , '男');

insert into Student values('02' , '钱电' , '1990-12-21' , '男');

insert into Student values('03' , '孙风' , '1990-12-20' , '男');

insert into Student values('04' , '李云' , '1990-12-06' , '男');

insert into Student values('05' , '周梅' , '1991-12-01' , '女');

insert into Student values('06' , '吴兰' , '1992-01-01' , '女');

insert into Student values('07' , '郑竹' , '1989-01-01' , '女');

insert into Student values('09' , '张三' , '2017-12-20' , '女');

insert into Student values('10' , '李四' , '2017-12-25' , '女');

insert into Student values('11' , '李四' , '2012-06-06' , '女');

insert into Student values('12' , '赵六' , '2013-06-13' , '女');

insert into Student values('13' , '孙七' , '2014-06-01' , '女');

科目表 Course

create table Course(CId varchar(10),Cname nvarchar(10),TId varchar(10));

insert into Course values('01' , '语文' , '02');

insert into Course values('02' , '数学' , '01');

insert into Course values('03' , '英语' , '03');

教师表 Teacher

create table Teacher(TId varchar(10),Tname varchar(10));

insert into Teacher values('01' , '张三');

insert into Teacher values('02' , '李四');

insert into Teacher values('03' , '王五');

成绩表 SC

create table SC(SId varchar(10),CId varchar(10),score decimal(18,1));

insert into SC values('01' , '01' , 80);

insert into SC values('01' , '02' , 90);

insert into SC values('01' , '03' , 99);

insert into SC values('02' , '01' , 70);

insert into SC values('02' , '02' , 60);

insert into SC values('02' , '03' , 80);

insert into SC values('03' , '01' , 80);

insert into SC values('03' , '02' , 80);

insert into SC values('03' , '03' , 80);

insert into SC values('04' , '01' , 50);

insert into SC values('04' , '02' , 30);

insert into SC values('04' , '03' , 20);

insert into SC values('05' , '01' , 76);

insert into SC values('05' , '02' , 87);

insert into SC values('06' , '01' , 31);

insert into SC values('06' , '03' , 34);

insert into SC values('07' , '02' , 89);

insert into SC values('07' , '03' , 98);

     -- 题目、解题思路及答案 

-- 1.查询" 01 "课程比" 02 "课程成绩高的学生的信息及课程分数
/*
 解题思路:将SC表分别通过课程号为01,02进行筛选后再进行两表联查,
         筛选出符合" 01 "课程比" 02 "课程成绩高的学生的学号,
         根据题目要求连接Student(学生表),筛选出相关学生的姓名
         等信息。
 */
select s.*, sc1.score, sc2.score
from Student s
         join SC sc1 on s.SId = sc1.SId and sc1.CId = 01
         join SC sc2 on s.SId = sc2.SId and sc2.CId = 02
where sc1.score > sc2.score;

-- 1.1 查询同时存在" 01 "课程和" 02 "课程的情况
/*
 解题思路:将SC表当作两张表进行查询,和第一题相似,根据题目需筛选出
          sc1表和sc2表的交集部分,选择内连接
 */
select sc2.SId, sc1.score, sc2.score, sc1.CId, sc2.CId
from SC sc1
         join SC sc2 on sc1.SId = sc2.SId
where sc1.CId = 01
  and sc2.CId = 02;

-- 1.2 查询存在" 01 "课程但可能不存在" 02 "课程的情况(不存在时显示为 null )
/*
 解题思路:
       查询SC表可知查询结果应存在06号学生且不存在07号学生,思路同上
 */

select sc1.SId, sc1.CId, sc2.CId, sc1.score, sc2.score
from SC sc1
         join SC sc2 on sc1.SId = sc2.SId
where sc1.CId = 01
  and sc2.CId >= 2;


-- 1.3 查询不存在" 01 "课程但存在" 02 "课程的情况
/*
 解题思路:
       查询SC可知查询结果应存在07号学生而不存在06号学生,思路同上
 */
select sc1.SId, sc1.CId, sc2.CId, sc1.score, sc2.score
from SC sc1
         join SC sc2 on sc1.SId = sc2.SId
where sc2.CId = 02
  and sc1.CId <> '02';


-- 2.查询平均成绩大于等于 60 分的同学的学生编号和学生姓名和平均成绩
/*
 解题思路:
      使用聚合函数avg计算出每个学生的平均分并筛选出符合平均分>=60的学生
      根据mysql语句的执行顺序:
      from >join >where >聚合函数 >having >select >distinct >order by >limit
      选择填写筛选条件
 */
select s.Sname, AVG(score) avg_score
from Student s,
     SC sc
where s.SId = sc.SId
group by s.Sname
having avg_score >= 60;


-- 3.查询在 SC 表存在成绩的学生信息
/*
 解题思路:
     查询SC表可知01-07号学生符合条件
 */

select distinct s.*
from SC sc
         join Student s on sc.SId = s.SId;


-- 4.查询所有同学的学生编号、学生姓名、选课总数、所有课程的成绩总和
/*
 解题思路:
     SC表和Student表两表联查
     使用聚合函数count计算选课,sum计算总分
 */
select s.SId, s.Sname, count(sc.CId) class_count, sum(sc.score)
from Student s
         left join SC sc on s.SId = sc.SId
group by s.SId, s.Sname;


-- 4.1显示没选课的学生(显示为NULL)
/*
 解题思路:
     SC表和Student表两表联查,CID为null的学生即没选课
     使用Cid为null当作筛选条件即可
 */
select s.*, sc.CId
from Student s
         left join SC sc on s.SId = sc.SId
where sc.CId is null;


-- 4.2查有成绩的学生信息
/*
 解题思路:同上
 */
select s.*, sc.CId
from Student s
         left join SC sc on s.SId = sc.SId
where sc.CId is not null;


-- 5.查询「李」姓老师的数量
/*
 解题思路:
     李姓老师只有一位,使用聚合函数count计算教师的数量,
     使用模拟查询like‘__%’筛选姓李的老师
 */
select count(Tname)
from Teacher
where Tname like '李%';


-- 6.查询学过「张三」老师授课的同学的信息
/*
 解题思路:
     使用自查询,在Teacher表中查询出张三的工号,
     再根据工号在Course表中查询出张三所授课程的课程号,
     根据课程号在SC表中可以查询出选择张三课程的学生学号,
     思路简单,就是联查的表多
 */
select s.*
from (select sc.SId id
      from Teacher t
               join Course c on t.TId = c.TId
               join SC sc on sc.CId = c.CId
      where t.Tname = '张三') t1
         join Student s
where s.SId = t1.id;


-- 7.查询没有学全所有课程的同学的信息
/*
 解题思路:
     使用聚合函数count,课程数少于3即没有学全课程
 */
select s.Sname, count(CId) c_count
from Student s
         join SC sc on s.SId = sc.SId
group by s.Sname
having c_count < 3;


-- 8.查询至少有一门课与学号为" 01 "的同学所学相同的同学的信息
/*
 解题思路:可知学号01的学生选择了全部3门课程
 */
-- 学号01的学生所学的课程
select sc.CId
from SC sc
where sc.SId = 01;

/*
 解题思路:
     只要有一门课程相同所以用in(....),Student表和SC表两表联查,
     最后筛选出课程号有一门与01学生相同且不是01学生的学生
 */
-- distinct(colum1, column2...) 返回指定的多个列中所有不重复的组合
select distinct s.*
from Student s
         join SC sc on s.SId = sc.SId
where sc.CId in (select sc.CId from SC sc where sc.SId = 01) and sc.SId <> '01';


-- 9.查询和" 01 "号的同学学习的课程完全相同的其他同学的信息
/*
 解题思路:
     本题一共三门课程,基本思路同第八题,查询出和01学生所学课程
     基本一致的学生且所选课程数要等于3才能保证和01学生所选课程一致
 */
select *
from Student s
where s.SId in (select sid
                from SC sc
                where sc.CId in (select distinct cid from SC where sid = '01')
                  and sid <> '01'
                group by sid
                having count(cid) = 3);


-- 10.查询没学过"张三"老师讲授的任一门课程的学生姓名
/*
 解题思路:
      本题的查询结果是06号学生以及其他没有选择课程的学生,
      筛选出没有选择张三的学生的学号,在联合Student进行查询,
      只要不在张三所教授的学生的学号列表里即可
 */

select s.* from Student s where s.SId not in(select sc.SId id
      from Teacher t
               join Course c on t.TId = c.TId
               join SC sc on sc.CId = c.CId
      where t.Tname = '张三');


-- 11.查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
/*
 解题思路:
      查询结果是04,06两个学生,可以先分组查询出哪些学生的不及格课程数大于等于2
 */
select sc.SId id, count(sc.SId) score_under_60
from SC sc
where sc.score < 60
group by sc.SId
having score_under_60 >= 2;
/*
 解题思路:
      再根据题目加上需要筛查出来其他条件
 */
select s.SId, s.Sname, avg(sc.score) avg_score
from (select sc.SId id, count(sc.SId) score_under_60
      from SC sc
      where sc.score < 60
      group by sc.SId
      having score_under_60 >= 2) t1
         join Student s on s.SId = t1.id
         join SC sc on s.SId = sc.SId
group by s.SId, s.Sname;


-- 12.检索" 01 "课程分数小于 60,按分数降序排列的学生信息
/*
 解题思路:
     加一个order by进行排序
 */
-- mysql默认升序
select s.*, sc.CId, sc.score
from Student s
         join SC sc on s.SId = sc.SId
where sc.CId = 01
  and score < 60
order by sc.score desc;


-- 13.按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩
/*
 解题思路:
     使用了窗口函数,直接添加一列
 */
-- 窗口函数over()当中如果不写 oder by就统计组内的所有数据,如果写了oder by 就统计第一行到当前行的数据
select s.*, sc.CId ,sc.score, avg(sc.score) over (partition by sc.SId) avg_score
from Student s
         join SC sc on s.SId = sc.SId;


-- 14.查询各科成绩最高分、最低分和平均分
-- 以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
-- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
-- 要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列

-- 课程 ID,课程 name,最高分,最低分,平均分
/*
 解题思路:
      及格率,中等率,优良率,优秀率略
 */
select distinct c.CId,
                c.Cname,
                min(score) over (partition by c.CId) min_score,
                max(score) over (partition by c.CId) max_score,
                avg(score) over (partition by c.CId) avg_score
from SC sc
         join Course c on sc.CId = c.CId;


-- 15.按各科成绩进行排序,并显示排名, Score 重复时保留名次空缺
/*
 解题思路:
     使用rank()可以在排名并列的时候保持排名的增加
 */
select sc.SId, s.Sname, c.Cname, rank() over (partition by sc.CId order by score) 'rank'
from SC sc
         join Student s on sc.SId = s.SId
         join Course c on sc.CId = c.CId;


-- 16.查询学生的总成绩,并进行排名,总分重复时不保留名次空缺
/*
 解题思路:
      思路同上,只是计算的分数不同且采用密集排名
 */
select s.Sname, dense_rank() over (order by t1.total_score) 'rank'
from (select SId, sum(score) total_score from SC group by SId) t1
         join Student s on s.SId = t1.SId;


-- 17.统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],
/*
 解题思路:
      加入了if判断语句和sum()函数搭配使用
 */
select sc.CId,
       c.Cname,
       sum(if(score between 85 and 100, 1, 0)) excellent,
       sum(if(score between 70 and 85, 1, 0))  normal
from Course c
         join SC sc on c.Cid = sc.CId
group by c.Cname, sc.CId;
  • 49
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
在Java中进行MySQL多表操作需要使用JDBC(Java Database Connectivity)技术,具体步骤如下: 1. 加载MySQL驱动程序 在Java中连接MySQL数据库需要加载MySQL驱动程序,可以使用Class.forName()方法加载。 ``` Class.forName("com.mysql.jdbc.Driver"); ``` 2. 建立数据库连接 使用DriverManager.getConnection()方法建立数据库连接,需要传入数据库URL、用户名和密码。 ``` String url = "jdbc:mysql://localhost:3306/test"; String user = "root"; String password = "123456"; Connection conn = DriverManager.getConnection(url, user, password); ``` 3. 创建Statement对象 使用Connection.createStatement()方法创建Statement对象,用于执行SQL语句。 ``` Statement stmt = conn.createStatement(); ``` 4. 执行SQL语句 使用Statement.executeUpdate()方法执行SQL语句,可以执行增、删、改操作。 ``` String sql = "insert into user(name, age) values('Tom', 20)"; stmt.executeUpdate(sql); ``` 使用Statement.executeQuery()方法执行SQL查询语句,返回ResultSet对象,可以遍历结果集获取查询结果。 ``` String sql = "select * from user"; ResultSet rs = stmt.executeQuery(sql); while(rs.next()) { String name = rs.getString("name"); int age = rs.getInt("age"); System.out.println(name + " " + age); } ``` 5. 关闭连接 使用Connection.close()方法关闭连接。 ``` conn.close(); ``` 以上是Java进行MySQL多表操作的基本步骤,具体操作需要根据业务需求来设计SQL语句。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值