登录
首页 >  数据库 >  MySQL

Mysql Sql 语句练习题(50道)

来源:脚本之家

时间:2023-01-07 12:06:16 223浏览 收藏

怎么入门数据库编程?需要学习哪些知识点?这是新手们刚接触编程时常见的问题;下面golang学习网就来给大家整理分享一些知识点,希望能够给初学者一些帮助。本篇文章就来介绍《Mysql Sql 语句练习题(50道)》,涉及到Mysql练习题,有需要的可以收藏一下

表名和字段

–1.学生表
Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别
–2.课程表
Course(c_id,c_name,t_id) – –课程编号, 课程名称, 教师编号
–3.教师表
Teacher(t_id,t_name) –教师编号,教师姓名
–4.成绩表
Score(s_id,c_id,s_score) –学生编号,课程编号,分数

测试数据

--建表
--学生表
CREATE TABLE `Student`(
`s_id` VARCHAR(20),
`s_name` VARCHAR(20) NOT NULL DEFAULT '',
`s_birth` VARCHAR(20) NOT NULL DEFAULT '',
`s_sex` VARCHAR(10) NOT NULL DEFAULT '',
PRIMARY KEY(`s_id`)
);
--课程表
CREATE TABLE `Course`(
`c_id` VARCHAR(20),
`c_name` VARCHAR(20) NOT NULL DEFAULT '',
`t_id` VARCHAR(20) NOT NULL,
PRIMARY KEY(`c_id`)
);
--教师表
CREATE TABLE `Teacher`(
`t_id` VARCHAR(20),
`t_name` VARCHAR(20) NOT NULL DEFAULT '',
PRIMARY KEY(`t_id`)
);
--成绩表
CREATE TABLE `Score`(
`s_id` VARCHAR(20),
`c_id` VARCHAR(20),
`s_score` INT(3),
PRIMARY KEY(`s_id`,`c_id`)
);
--插入学生表测试数据
insert into Student values('01' , '赵雷' , '1990-01-01' , '男');
insert into Student values('02' , '钱电' , '1990-12-21' , '男');
insert into Student values('03' , '孙风' , '1990-05-20' , '男');
insert into Student values('04' , '李云' , '1990-08-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吴兰' , '1992-03-01' , '女');
insert into Student values('07' , '郑竹' , '1989-07-01' , '女');
insert into Student values('08' , '王菊' , '1990-01-20' , '女');
--课程表测试数据
insert into Course values('01' , '语文' , '02');
insert into Course values('02' , '数学' , '01');
insert into Course values('03' , '英语' , '03');

--教师表测试数据
insert into Teacher values('01' , '张三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');

--成绩表测试数据
insert into Score values('01' , '01' , 80);
insert into Score values('01' , '02' , 90);
insert into Score values('01' , '03' , 99);
insert into Score values('02' , '01' , 70);
insert into Score values('02' , '02' , 60);
insert into Score values('02' , '03' , 80);
insert into Score values('03' , '01' , 80);
insert into Score values('03' , '02' , 80);
insert into Score values('03' , '03' , 80);
insert into Score values('04' , '01' , 50);
insert into Score values('04' , '02' , 30);
insert into Score values('04' , '03' , 20);
insert into Score values('05' , '01' , 76);
insert into Score values('05' , '02' , 87);
insert into Score values('06' , '01' , 31);
insert into Score values('06' , '03' , 34);
insert into Score values('07' , '02' , 89);
insert into Score values('07' , '03' , 98);

表数据如下

student 学生表:

s_id s_name s_birth s_sex
01 赵雷 1990-01-01
02 钱电 1990-12-21
03 孙凤 1990-05-20
04 李云 1990-08-06
05 周梅 1991-12-12
06 吴兰 2017-12-13
07 郑竹 1989-07-01
08 王菊 1990-01-20
09 赵雷 1990-01-21
10 赵雷 1990-01-22

score 分数表:

s_id c_id s_score
01 01 80
01 02 90
01 03 99
02 01 70
02 02 60
02 03 80
03 01 80
03 02 80
03 03 80
04 01 50
04 02 30
04 03 20
05 01 76
05 03 87
06 01 31
06 03 34
07 03 89
07 01 98

course 课程表

c_id c_name t_id
01 语文 02
02 数学 01
03 英语 03

teacher 老师表:

t_id t_name
01 张三
02 李四
03 王五
-- 准备条件,去掉 sql_mode 的 ONLY_FULL_GROUP_BY 否则此种情况下会报错:
-- Expression #1 of select list is not in group by clause and contains nonaggregated column 'userinfo.
-- 原因:
-- MySQL 5.7.5和up实现了对功能依赖的检测。如果启用了only_full_group_by SQL模式(在默认情况下是这样),
-- 那么MySQL就会拒绝选择列表、条件或顺序列表引用的查询,这些查询将引用组中未命名的非聚合列,而不是在功能上依赖于它们。
-- (在5.7.5之前,MySQL没有检测到功能依赖项,only_full_group_by在默认情况下是不启用的。关于前5.7.5行为的描述,请参阅MySQL 5.6参考手册。)
-- 执行以下个命令,可以查看 sql_mode 的内容。
SHOW SESSION VARIABLES;
SHOW GLOBAL VARIABLES;
select @@sql_mode;
-- 更改
set global sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
set session sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';

练习题和sql

-- 1、查询"01"课程比"02"课程成绩高的学生的信息及课程分数 
select st.*,sc.s_score as '语文' ,sc2.s_score '数学' 
from student st
left join score sc on sc.s_id=st.s_id and sc.c_id='01' 
left join score sc2 on sc2.s_id=st.s_id and sc2.c_id='02' 
where sc.s_score>sc2.s_score

-- 2、查询"01"课程比"02"课程成绩低的学生的信息及课程分数
select st.*,sc.s_score '语文',sc2.s_score '数学' from student st
left join score sc on sc.s_id=st.s_id and sc.c_id='01'
left join score sc2 on sc2.s_id=st.s_id and sc2.c_id='02'
where sc.s_score=60

-- 4、查询平均成绩小于60分的同学的学生编号和学生姓名和平均成绩
  -- (包括有成绩的和无成绩的)
select st.s_id,st.s_name,(case when ROUND(AVG(sc.s_score),2) is null then 0 else ROUND(AVG(sc.s_score)) end ) cjScore from student st
left join score sc on sc.s_id=st.s_id
group by st.s_id having AVG(sc.s_score)1

-- 10、查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息
select st.* from student st 
inner join score sc on sc.s_id = st.s_id
inner join course c on c.c_id=sc.c_id and c.c_id="01"
where st.s_id not in (
select st2.s_id from student st2 
inner join score sc2 on sc2.s_id = st2.s_id
inner join course c2 on c2.c_id=sc2.c_id and c2.c_id="02"
)

-- 11、查询没有学全所有课程的同学的信息
 -- 太复杂,下次换一种思路,看有没有简单点方法
 -- 此处思路为查学全所有课程的学生id,再内联取反面
select * from student where s_id not in (
select st.s_id from student st 
inner join score sc on sc.s_id = st.s_id and sc.c_id="01"
where st.s_id in (
select st2.s_id from student st2 
inner join score sc2 on sc2.s_id = st2.s_id and sc2.c_id="02"
) and st.s_id in (
select st2.s_id from student st2 
inner join score sc2 on sc2.s_id = st2.s_id and sc2.c_id="03"
))
-- 来自一楼网友的思路,左连接,根据学生id分组过滤掉 数量小于 课程表中总课程数量的结果(show me his code),简洁不少。
select st.* from Student st
left join Score S
on st.s_id = S.s_id
group by st.s_id
having count(c_id)=2
)
group by st.s_id

-- 16、检索"01"课程分数小于60,按分数降序排列的学生信息
select st.*,sc.s_score from student st 
inner join score sc on sc.s_id=st.s_id and sc.c_id="01" and sc.s_score=60,中等为:70-80,优良为:80-90,优秀为:>=90
select c.c_id,c.c_name,max(sc.s_score) "最高分",MIN(sc2.s_score) "最低分",avg(sc3.s_score) "平均分" 
,((select count(s_id) from score where s_score>=60 and c_id=c.c_id )/(select count(s_id) from score where c_id=c.c_id)) "及格率"
,((select count(s_id) from score where s_score>=70 and s_score=80 and s_score=90 and c_id=c.c_id )/(select count(s_id) from score where c_id=c.c_id)) "优秀率"
from course c
left join score sc on sc.c_id=c.c_id 
left join score sc2 on sc2.c_id=c.c_id 
left join score sc3 on sc3.c_id=c.c_id 
group by c.c_id

-- 19、按各科成绩进行排序,并显示排名(实现不完全)
-- mysql没有rank函数
-- 加@score是为了防止用union all 后打乱了顺序
select c1.s_id,c1.c_id,c1.c_name,@score:=c1.s_score,@i:=@i+1 from (select c.c_name,sc.* from course c 
left join score sc on sc.c_id=c.c_id
where c.c_id="01" order by sc.s_score desc) c1 ,
(select @i:=0) a
union all 
select c2.s_id,c2.c_id,c2.c_name,c2.s_score,@ii:=@ii+1 from (select c.c_name,sc.* from course c 
left join score sc on sc.c_id=c.c_id
where c.c_id="02" order by sc.s_score desc) c2 ,
(select @ii:=0) aa 
union all
select c3.s_id,c3.c_id,c3.c_name,c3.s_score,@iii:=@iii+1 from (select c.c_name,sc.* from course c 
left join score sc on sc.c_id=c.c_id
where c.c_id="03" order by sc.s_score desc) c3;
set @iii=0;


-- 20、查询学生的总成绩并进行排名
select st.s_id,st.s_name
,(case when sum(sc.s_score) is null then 0 else sum(sc.s_score) end)
 from student st
left join score sc on sc.s_id=st.s_id
group by st.s_id order by sum(sc.s_score) desc

-- 21、查询不同老师所教不同课程平均分从高到低显示 
select t.t_id,t.t_name,c.c_name,avg(sc.s_score) from teacher t 
left join course c on c.t_id=t.t_id 
left join score sc on sc.c_id =c.c_id
group by t.t_id
order by avg(sc.s_score) desc

-- 22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
select a.* from (
select st.*,c.c_id,c.c_name,sc.s_score from student st
left join score sc on sc.s_id=st.s_id
inner join course c on c.c_id =sc.c_id and c.c_id="01"
order by sc.s_score desc LIMIT 1,2 ) a
union all
select b.* from (
select st.*,c.c_id,c.c_name,sc.s_score from student st
left join score sc on sc.s_id=st.s_id
inner join course c on c.c_id =sc.c_id and c.c_id="02"
order by sc.s_score desc LIMIT 1,2) b
union all
select c.* from (
select st.*,c.c_id,c.c_name,sc.s_score from student st
left join score sc on sc.s_id=st.s_id
inner join course c on c.c_id =sc.c_id and c.c_id="03"
order by sc.s_score desc LIMIT 1,2) c

-- 23、统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比
select c.c_id,c.c_name 
,((select count(1) from score sc where sc.c_id=c.c_id and sc.s_score80)/(select count(1) from score sc where sc.c_id=c.c_id )) "100-85"
,((select count(1) from score sc where sc.c_id=c.c_id and sc.s_score70)/(select count(1) from score sc where sc.c_id=c.c_id )) "85-70"
,((select count(1) from score sc where sc.c_id=c.c_id and sc.s_score60)/(select count(1) from score sc where sc.c_id=c.c_id )) "70-60"
,((select count(1) from score sc where sc.c_id=c.c_id and sc.s_score=0)/(select count(1) from score sc where sc.c_id=c.c_id )) "60-0"
from course c order by c.c_id

-- 24、查询学生平均成绩及其名次 
set @i=0;
select a.*,@i:=@i+1 from (
select st.s_id,st.s_name,round((case when avg(sc.s_score) is null then 0 else avg(sc.s_score) end),2) "平均分" from student st
left join score sc on sc.s_id=st.s_id
group by st.s_id order by sc.s_score desc) a

-- 25、查询各科成绩前三名的记录
select a.* from (
 select st.s_id,st.s_name,c.c_id,c.c_name,sc.s_score from student st
 left join score sc on sc.s_id=st.s_id
 inner join course c on c.c_id=sc.c_id and c.c_id='01'
 order by sc.s_score desc LIMIT 0,3) a
union all 
select b.* from (
 select st.s_id,st.s_name,c.c_id,c.c_name,sc.s_score from student st
 left join score sc on sc.s_id=st.s_id
 inner join course c on c.c_id=sc.c_id and c.c_id='02'
 order by sc.s_score desc LIMIT 0,3) b
union all
select c.* from (
 select st.s_id,st.s_name,c.c_id,c.c_name,sc.s_score from student st
 left join score sc on sc.s_id=st.s_id
 inner join course c on c.c_id=sc.c_id and c.c_id='03'
 order by sc.s_score desc LIMIT 0,3) c

-- 26、查询每门课程被选修的学生数 
select c.c_id,c.c_name,count(1) from course c 
left join score sc on sc.c_id=c.c_id
inner join student st on st.s_id=c.c_id
group by st.s_id

-- 27、查询出只有两门课程的全部学生的学号和姓名
select st.s_id,st.s_name from student st 
left join score sc on sc.s_id=st.s_id
inner join course c on c.c_id=sc.c_id 
group by st.s_id having count(1)=2

-- 28、查询男生、女生人数
select st.s_sex,count(1) from student st group by st.s_sex

-- 29、查询名字中含有"风"字的学生信息
select st.* from student st where st.s_name like "%风%";

-- 30、查询同名同性学生名单,并统计同名人数 
select st.*,count(1) from student st group by st.s_name,st.s_sex having count(1)>1

-- 31、查询1990年出生的学生名单
select st.* from student st where st.s_birth like "1990%";

-- 32、查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列 
select c.c_id,c.c_name,avg(sc.s_score) from course c
inner join score sc on sc.c_id=c.c_id 
group by c.c_id order by avg(sc.s_score) desc,c.c_id asc

-- 33、查询平均成绩大于等于85的所有学生的学号、姓名和平均成绩
select st.s_id,st.s_name,avg(sc.s_score) from student st
left join score sc on sc.s_id=st.s_id
group by st.s_id having avg(sc.s_score)>=85

-- 34、查询课程名称为"数学",且分数低于60的学生姓名和分数 
select st.s_id,st.s_name,sc.s_score from student st
inner join score sc on sc.s_id=st.s_id and sc.s_score=70)
order by s_id

-- 37、查询不及格的课程
select st.s_id,c.c_name,st.s_name,sc.s_score from student st
inner join score sc on sc.s_id=st.s_id and sc.s_score=80

-- 39、求每门课程的学生人数
select c.c_id,c.c_name,count(1) from course c
inner join score sc on sc.c_id=c.c_id
group by c.c_id

-- 40、查询选修"张三"老师所授课程的学生中,成绩最高的学生信息及其成绩 
select st.*,c.c_name,sc.s_score,t.t_name from student st
inner join score sc on sc.s_id=st.s_id
inner join course c on c.c_id=sc.c_id 
inner join teacher t on t.t_id=c.t_id and t.t_name="张三"
order by sc.s_score desc
limit 0,1

-- 41、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩 
select st.s_id,st.s_name,sc.c_id,sc.s_score from student st 
left join score sc on sc.s_id=st.s_id
left join course c on c.c_id=sc.c_id
where (
select count(1) from student st2 
left join score sc2 on sc2.s_id=st2.s_id
left join course c2 on c2.c_id=sc2.c_id
where sc.s_score=sc2.s_score and c.c_id!=c2.c_id 
)>1

-- 42、查询每门功成绩最好的前两名 
select a.* from (select st.s_id,st.s_name,c.c_name,sc.s_score from student st
left join score sc on sc.s_id=st.s_id
inner join course c on c.c_id=sc.c_id and c.c_id="01"
order by sc.s_score desc limit 0,2) a
union all
select b.* from (select st.s_id,st.s_name,c.c_name,sc.s_score from student st
left join score sc on sc.s_id=st.s_id
inner join course c on c.c_id=sc.c_id and c.c_id="02"
order by sc.s_score desc limit 0,2) b
union all
select c.* from (select st.s_id,st.s_name,c.c_name,sc.s_score from student st
left join score sc on sc.s_id=st.s_id
inner join course c on c.c_id=sc.c_id and c.c_id="03"
order by sc.s_score desc limit 0,2) c
 
-- 借鉴(更准确,漂亮):
 select a.s_id,a.c_id,a.s_score from score a
 where (select COUNT(1) from score b where b.c_id=a.c_id and b.s_score>=a.s_score)5
order by count(1) desc,sc.c_id asc

-- 44、检索至少选修两门课程的学生学号 
select st.s_id from student st 
left join score sc on sc.s_id=st.s_id
group by st.s_id having count(1)>=2

-- 45、查询选修了全部课程的学生信息
select st.* from student st 
left join score sc on sc.s_id=st.s_id
group by st.s_id having count(1)=(select count(1) from course)

-- 46、查询各学生的年龄
 select st.*,timestampdiff(year,st.s_birth,now()) from student st

-- 47、查询本周过生日的学生
 -- 此处可能有问题,week函数取的为当前年的第几周,2017-12-12是第50周而2018-12-12是第49周,可以取月份,day,星期几(%w),
 -- 再判断本周是否会持续到下一个月进行判断,太麻烦,不会写
select st.* from student st 
where week(now())=week(date_format(st.s_birth,'%Y%m%d'))

-- 48、查询下周过生日的学生
select st.* from student st 
where week(now())+1=week(date_format(st.s_birth,'%Y%m%d'))

-- 49、查询本月过生日的学生
select st.* from student st 
where month(now())=month(date_format(st.s_birth,'%Y%m%d'))

-- 50、查询下月过生日的学生
 -- 注意:当 当前月为12时,用month(now())+1为13而不是1,可用timestampadd()函数或mod取模
select st.* from student st 
where month(timestampadd(month,1,now()))=month(date_format(st.s_birth,'%Y%m%d'))
-- 或
select st.* from student st where (month(now()) + 1) mod 12 = month(date_format(st.s_birth,'%Y%m%d'))

以上就是本文的全部内容了,是否有顺利帮助你解决问题?若是能给你带来学习上的帮助,请大家多多支持golang学习网!更多关于数据库的相关知识,也可关注golang学习网公众号。

声明:本文转载于:脚本之家 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>
评论列表