MysqlSql语句练习题(50道)
MySql 语句练习50题
表名和字段
–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' , '李四');
php srorminsert 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 010180
010290
010399
020170
020260
020380
030180
030280
030380
040150
040230
040320
050176
050387
060131
060334
070389
070198
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;openstack rocky
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<sc2.s_score
-- 3、查询平均成绩⼤于等于60分的同学的学⽣编号和学⽣姓名和平均成绩
select st.s_id,st.s_name,ROUND(AVG(sc.s_score),2) 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)>=60
mysql语句分类-- 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)<60 or AVG(sc.s_score) is NULL
-- 5、查询所有同学的学⽣编号、学⽣姓名、选课总数、所有课程的总成绩
select st.s_id,st.s_name,count(c.c_id),( case when SUM(sc.s_score) is null or sum(sc.s_score)="" then 0 else SUM(sc.s_score) end) 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
group by st.s_id
-- 6、查询"李"姓⽼师的数量
select t.t_name,count(t.t_id) from teacher t
group by t.t_id having t.t_name like "李%";
-- 7、查询学过"张三"⽼师授课的同学的信息
select st.* from student streturn的所有形式
left join score sc on sc.s_id=st.s_id
left join course c on c.c_id=sc.c_id
个人主页动态left join teacher t on t.t_id=c.t_id
where t.t_name="张三"
-- 8、查询没学过"张三"⽼师授课的同学的信息
-- 张三⽼师教的课
select c.* from course c left join teacher t on t.t_id=c.t_id where t.t_name="张三"
-
- 有张三⽼师课成绩的st.s_id
select sc.s_id from score sc where sc.c_id in (select c.c_id from course c left join teacher t on t.t_id=c.t_id where t.t_name="张三")
-- 不在上⾯查到的st.s_id的学⽣信息,即没学过张三⽼师授课的同学信息
select st.* from student st where st.s_id not in(
select sc.s_id from score sc where sc.c_id in (select c.c_id from course c left join teacher t on t.t_id=c.t_id where t.t_name="张三")
)
-- 9、查询学过编号为"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 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"
)
⽹友提供的思路(厉害呦~):
SELECT st.*
FROM student st
INNER JOIN score sc ON sc.`s_id`=st.`s_id`
GROUP BY st.`s_id`
HAVING SUM(IF(sc.`c_id`="01" OR sc.`c_id`="02" ,1,0))>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)<(select count(c_id) from Course)
-- 12、查询⾄少有⼀门课与学号为"01"的同学所学相同的同学的信息
select distinct st.* from student st
left join score sc on sc.s_id=st.s_id
where sc.c_id in (
select sc2.c_id from student st2
left join score sc2 on sc2.s_id=st2.s_id
where st2.s_id ='01'
)
-- 13、查询和"01"号的同学学习的课程完全相同的其他同学的信息
select st.* from student st
left join score sc on sc.s_id=st.s_id
group by st.s_id
having group_concat(sc.c_id) =
(
select group_concat(sc2.c_id) from student st2
left join score sc2 on sc2.s_id=st2.s_id
where st2.s_id ='01'
)
-- 14、查询没学过"张三"⽼师讲授的任⼀门课程的学⽣姓名
select st.s_name from student st
where st.s_id not in (
select sc.s_id from score sc
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="张三"
)
-- 15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
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
where sc.s_id in (
select sc.s_id from score sc
where sc.s_score<60 or sc.s_score is NULL
group by sc.s_id having COUNT(sc.s_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
order by sc.s_score desc
-
- 17、按平均成绩从⾼到低显⽰所有学⽣的所有课程的成绩以及平均成绩
-- 可加round,case when then else end 使显⽰更完美
select st.s_id,st.s_name,avg(sc4.s_score) "平均分",sc.s_score "语⽂",sc2.s_score "数学",sc3.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"
left join score sc3 on sc3.s_id=st.s_id and sc3.c_id="03"
left join score sc4 on sc4.s_id=st.s_id
group by st.s_id
order by SUM(sc4.s_score) desc
-- 18.查询各科成绩最⾼分、最低分和平均分:以如下形式显⽰:课程ID,课程name,最⾼分,最低分,平均分,及格率,中等率,优良率,优秀率-- 及格为>=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 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>=80 and s_score<90 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>=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_score<=100 and sc.s_score>80)/(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_score<=85 and sc.s_score>70)/(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_score<=70 and sc.s_score>60)/(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<=60 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、查询出只有两门课程的全部学⽣的学号和姓名
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论