MySQL练习50道

MySQL练习

50道经典SQL练习题

数据表介绍

  • 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)
    ); 
    
  • 课程表 Course

    create table Course(
        CId varchar(10),
        Cname varchar(10),
        TId varchar(10)
    );
    
  • 教师表 Teacher

    create table Teacher(
        TId varchar(10),
        Tname varchar(10)
    );
    
  • 成绩表 SC

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

插入数据

  • 学⽣表 Student

    -- 学生表 Student
    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' , '女'); 
    insert into Student values('14' , '李四' , '2012-06-06' , '女'); 
    insert into Student values('14' , '李四' , '2012-09-04' , '女'); 
    
    
  • 课程表 Course

    -- 科⽬表 Course 
    insert into Course values('01' , '语⽂' , '02'); 
    insert into Course values('02' , '数学' , '01'); 
    insert into Course values('03' , '英语' , '03');
    
  • 教师表 Teacher

    -- 教师表 Teacher 
    insert into Teacher values('01' , '张三'); 
    insert into Teacher values('02' , '李四'); 
    insert into Teacher values('03' , '王五'); 
    
  • 成绩表 SC

    -- 成绩表 SC 
    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 "课程成绩⾼的学⽣的信息及课程分数
-- 单独取出课程,再关联
select c.*,d.score01,d.score02,e.score as score03 from 
Student as c
join
(
    select a.SID ,a.score as score01,b.score as score02 from 
    (select * from SC where Cid='01') as a
    left join
    (select * from SC where Cid='02') as b
    on a.Sid=b.SId
    where a.score > if(b.score is null,0 ,b.score)
 ) as d
 on c.SId=d.SId
 join 
 (select * from SC where Cid='01') as e
 on c.SId=e.Sid;
 
 
 
 select a.*,b.score01,b.score02,b.score03 from 
 Student as a
 join
 (
     select 
         Sid,
         sum(case when CId='01' then score else 0 end)  as score01,
         sum(case when CId='02' then score else 0 end)  as score02,
         sum(case when CId='03' then score else 0 end)  as score03
     from 
         SC
     group by Sid
     having score01 > score02
 ) as b
 on a.SId=b.SId;
2.查询同时存在" 01 “课程和” 02 "课程的情况
	select 
         Sid,
         sum(case when CId='01' then score else 0 end)  as score01,
         sum(case when CId='02' then score else 0 end)  as score02,
         sum(case when CId='03' then score else 0 end)  as score03
     from 
         SC
     group by Sid
     having score01 > 0 and score02 > 0;
3.查询存在" 01 “课程但可能不存在” 02 "课程的情况(不存在时显示为 null )
	select 
         Sid,
         sum(case when CId='01' then score else 0 end)  as score01,
         sum(case when CId='02' then score else null end)  as score02,
         sum(case when CId='03' then score else 0 end)  as score03
     from 
         SC
     group by Sid
     having score01 > 0;
4.查询不存在" 01 “课程但存在” 02 "课程的情况
	select 
         Sid,
         sum(case when CId='01' then score else 0 end)  as score01,
         sum(case when CId='02' then score else null end)  as score02,
         sum(case when CId='03' then score else 0 end)  as score03
     from 
         SC
     group by Sid
     having score01 = 0 and score02 > 0
5.查询平均成绩⼤于等于 60 分的同学的学⽣编号和学⽣姓名和平均成绩
select 
    a.SId,
    b.Sname,
    avg(score) as avg_score 
from 
    SC as a
join 
    Student as b
on
    a.Sid=b.Sid
group by 
    a.SId,b.Sname
having 
	avg_score > 60;

PS:round(m,n)函数将字段m的查询结果保留小数点n位

6.查询在 SC 表存在成绩的学⽣信息
select distinct a.* from 
Student as a
join
SC as b
on a.SId=b.SId;


select * from 
Student 
where Sid in (select distinct Sid from SC);

PS:DISTINCT 将后面的字段的查询结果进行去重。

7.查询所有同学的学⽣编号、学⽣姓名、选课总数、所有课程的总成绩(没成绩的显示为 null )
select  a.SId,a.Sname,count(b.SId) as num,sum(b.score) as sum_score from 
Student as a
left join 
SC as b
on
a.SId=b.Sid
group by a.SId,a.Sname;
8.查询「李」姓⽼师的数量
select count(1) as num from 
Teacher
where Tname like '李%'
9.查询学过「张三」⽼师授课的同学的信息
SELECT
	*
FROM
	Student
WHERE
	SId IN (
		SELECT
			Sid
		FROM
			SC
		WHERE
			CId IN (
				SELECT
					Cid
				FROM
					Course
				WHERE
					TId = (
						SELECT
							TId
						FROM
							Teacher
						WHERE
							Tname = '张三'
					)
			)
	)
10.查询没有学全所有课程的同学的信息
select a.SId,a.Sname,a.Sage,a.Ssex,count(b.SId) as num from 
Student as a
left join
SC as b
on a.SId=b.SId
group by a.SId,a.Sname,a.Sage,a.Ssex
having num < (select count(1) from Course)
11.查询⾄少有⼀⻔课与学号为" 01 "的同学所学相同的同学的信息
select * from 
Student
where 
Sid in 
(select distinct  SId from SC
where Sid!='01' and  CId in (select CId from SC where SId='01'))
12.查询和" 01 "号的同学学习的课程 完全相同的其他同学的信息
create view v_tmp as select CId from SC where SId='01';

select * from Student
where 
SId in 
(
    SELECT
        SId
    FROM
        SC
    WHERE
        SId IN (
            SELECT
                SId
            FROM
                SC
            WHERE
                SId != '01'
            GROUP BY
                SId
            HAVING
                count(1) = ( -- 1、第一次取出课程数量和01相同的学生
                    SELECT
                        count(1) AS num
                    FROM
                        v_tmp
                )
        )
    AND CId IN (SELECT * FROM v_tmp)-- 2、取出至少有一个课程和01相同的学生
    GROUP BY
        SId
    HAVING
        count(1) = ( -- 3、取出和01完全相同的学生
            SELECT
                count(1) AS num
            FROM
                v_tmp
        )
 );
 
 
 select * from 
 Student
 where Sid in 
 (
     select a.SId from 
     (select 
     Sid,
        max(case when CId='01' then CId else '' end)  as score01,
        max(case when CId='02' then CId else '' end)  as score02,
        max(case when CId='03' then CId else '' end)  as score03
     from 
     SC
     where SId!='01'
     group by 
     SId) as a,
     (select 
     Sid,
        max(case when CId='01' then CId else '' end)  as score01,
        max(case when CId='02' then CId else '' end)  as score02,
        max(case when CId='03' then CId else '' end)  as score03
     from 
     SC
     where SId='01'
     group by 
     SId) as b
     where 
     a.score01=b.score01 and a.score02=b.score02 and a.score03=b.score03
 );
 
 
select
     Sid,
     group_concat(CId order by CId) 
from 
     SC
 group by 
     Sid
13.查询没学过"张三"⽼师讲授的任⼀⻔课程的学⽣姓名

select * from 
Student
where
SId not in 
(select Sid from 
SC
where Cid  in 
(select Cid from 
Course
where 
TId = (select TId from Teacher where Tname = '张三')));
14.查询两⻔及其以上不及格课程的同学的学号,姓名及其平均成绩

select a.SId,a.Sname,b.avg_score from 
Student as a
join
(select 
    SId,
    -- count(case when score < 60 then 1 else null end) as num, -- 统计没几个科目的数量
 	sum(case when score < 60 then 1 else 0 end) as num,
    avg(score) as avg_score
from 
    SC
group by SId
having num >= 2) as b
on a.SId=b.SId;
15.检索" 01 "课程分数⼩于 60,按分数降序排列的学⽣信息
select b.* from 
SC as a
join
Student as b
on a.Sid=b.Sid
where Cid='01' and score < 60
order by a.score desc;

16.按平均成绩从⾼到低显示所有学⽣的所有课程的成绩以及平均成绩

select a.*,b.avg_score from
SC as a
join
(select 
Sid,
avg(score) as avg_score
from 
SC
group by Sid) as b
on a.SId=b.SId
order by b.avg_score desc;
17.查询各科成绩最⾼分、最低分和平均分: 以如下形式显示:课程 ID,课程 name,最⾼分,最低分,平均分,及格率,中等率,优良率,优秀率 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90要求输出课程号和选修⼈数,查询结果按⼈数降序排列,若⼈数相同,按课程号升序排列
	select 
        CId,
        max(score) as max_score,
        min(score) as min_score,
        avg(score) as avg_score,
        round(count(case when score >=60 then 1 else null end) / count(1) *100,2) as p,
        round(count(case when score >=70 and score<80 then 1 else null end) / count(1) *100,2) as p,
        round(count(case when score >=80 and score<90 then 1 else null end) / count(1) *100,2) as p,
        round(count(case when score >=90  then 1 else null end) / count(1) *100,2) as p
    from 
        SC
	group by 
        CId
    order by count(1) desc ,CId asc;
	

concat()用作字符串拼接

concat(‘1’ , ’+’ , ’1’ , ‘=’ , ‘2’) ==> 1+1=2

case when 条件判断

CASE WHEN sc.score>=60 THEN 1 ELSE 0 END

意思是sc.score>=60这个条件成立时,返回1,不成立时返回0

18.按各科平均成绩进⾏排序,并显示排名, Score 重复时保留名次空缺
SELECT @i:=0;
select Cid,avg(score) as avg_score ,(@i:=@i+1) from
SC
group by 
Cid
order by avg_score;


select c.*,d.rank from 
SC as c
join
(select score,min(rank) as rank from (
    select a.*,(@i:=@i+1) as rank from 
    SC as a,
    (SELECT @i:=0) AS j 
    order by score
) as b
group by score) as d
on c.score = d.score
order by rank asc;
19.按各科平均成绩进⾏排序,并显示排名, Score 重复时不保留名次空缺

(@i:=@i+1)代表定义一个变量,每次叠加1;

(SELECT @i:=0) AS j 代表建立一个临时表,j是随便取的表名,但别名一定要的。

select Cid,avg(score) as avg_score ,(@i:=@i+1) from
SC,
(SELECT @i:=0) AS j 
group by 
Cid
order by avg_score;
20.查询学⽣的总成绩,并进⾏排名,总分重复时保留名次空缺
select a.*,(@i:=@i+1) as rank from 
(
    select SId,sum(score) as sum_score from
    SC
    group by 
    SId
    order by sum_score desc
) as a,
(SELECT @i:=0) AS j 
21.查询学⽣的总成绩,并进⾏排名,总分重复时不保留名次空缺
select a.*,(@i:=@i+1) as rank from 
(
    select SId,sum(score) as sum_score from
    SC
    group by 
    SId
    order by sum_score desc
) as a,
(SELECT @i:=0) AS j 
22.统计各科成绩各分数段⼈数:课程编号,课程名称,[100-85],[85-70],[70-60],[60-0]及所占百分⽐

select a.*,a.num / b.num * 100 as p from
(select 
    CId,
    case 
    when score >= 0 and score <=60 then '[0-60]'
    when score > 60 and score <=70 then '[60-70]'
    when score > 70 and score <=85 then '[7-85]'
    else '[85-10]' end as flow,
    count(1) as num
from
    SC
group by 
    Cid,
    case 
    when score >= 0 and score <=60 then '[0-60]'
    when score > 60 and score <=70 then '[60-70]'
    when score > 70 and score <=85 then '[7-85]'
    else '[85-10]' end
) as a
join
    (select Cid,count(1) as num from 
    SC
    group by Cid
) as b

23.查询各科成绩前三名的记录

再hive中使用row_number(()实现

(select * from 
SC
where CId='01'
order by score
limit 3)
union all
(select * from 
SC
where CId='02'
order by score
limit 3)
union all
(select * from 
SC
where CId='03'
order by score
limit 3)
24.查询每⻔课程被选修的学⽣数
select Cid,count(1) as num from 
SC
group by CId
25.查询出只选修两⻔课程的学⽣学号和姓名

select a.Sid,a.SName from 
Student as a
join
(select SId,count(1) as num from
SC
group by SId
having num = 2
) as b
on a.Sid=b.Sid
26.查询男⽣、⼥⽣⼈数
select SSex,count(1) as num from 
Student
group by 
SSex
27.查询名字中含有「⻛」字的学⽣信息
select * from 
Student
where 
Sname like '%风%'
28.查询同名同性学⽣名单,并统计同名⼈数
select distinct  a.* from 
Student as a
join
Student as b
on a.SName=b.Sname and a.SId!=b.SId


select count(distinct a.SId) as num from 
Student as a
join
Student as b
on a.SName=b.Sname and a.SId!=b.SId;
29.查询 1990 年出⽣的学⽣名单
select * from Student where year(Sage)='1990';
select * from Student where substring(Sage,1,4)='1990';
30.查询每⻔课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号升序排列
select CId,avg(score) as avg_score from 
SC
group by CId
order by avg_score desc,Cid asc

31.查询平均成绩⼤于等于 85 的所有学⽣的学号、姓名和平均成绩

select a.SId,b.SName,avg(score) as avg_score from 
SC as a
join
Student as b
on a.Sid=b.Sid
group by 
a.SId,b.SName
having avg_score >= 85;

32.查询课程名称为「数学」,且分数低于 60 的学⽣姓名和分数

select b.Sname,a.score from 
SC as a
join
Student as b
on a.Sid=b.Sid
where Cid = (select Cid from Course where CName = '数学') 
and score >= 60
33.查询所有学⽣的课程及分数情况(存在学⽣没成绩,没选课的情况)
select * from 
Student as a
left join
SC as b
on a.Sid=b.Sid
34.查询任何⼀⻔课程成绩在 70 分以上的姓名、课程名称和分数
select a.SName,c.Cname,b.score from
Student as a
join
SC as b
on
a.SId=b.SId
join
Course as c
on b.Cid=c.Cid
where a.Sid in (select distinct Sid from SC where score > 70) ;


select a.SName,c.Cname,b.score from
(
    select * from 
    Student 
    where Sid in (select distinct Sid from SC where score > 70) -- 下层过滤器,减少关联的数据量
) as a
join
SC as b
on
a.SId=b.SId
join
Course as c
on b.Cid=c.Cid
35.查询不及格的课程
select * from
SC
where score < 60
36.查询课程编号为 01 且课程成绩在 80 分以上的学⽣的学号和姓名
select a.Sid,b.Sname,a.score from
SC as a
join
Student as b
on a.Sid=b.sid
where
CId='01' and score >= 80
37.求每⻔课程的学⽣⼈数
select CId,count(1) as num from
SC
group by CId

38.成绩不重复的情况下,查询选修「张三」⽼师所授课程的学⽣中,成绩最⾼的学⽣信息及其成绩
select * from 
Student as a
join
(
    select * from 
    SC
    where Cid in(
    select Cid from 
    Course
    where Tid=(select TId from Teacher where Tname ='张三')
    )
    order by score desc
    limit 1
) as b
on a.Sid=b.Sid;
39.成绩有重复的情况下,查询选修「张三」⽼师所授课程的学⽣中,成绩最⾼的学⽣信息及其成绩

40.查询不同课程成绩相同的学⽣的学⽣编号、课程编号、学⽣成绩
select a.* from 
SC as a,
SC as b
where a.Sid!=b.Sid and a.CId!=b.Cid and a.score=b.score;
41.查询每⻔课程成绩最好的前两名
(select * from 
SC
where CId='01'
order by score
limit 2)
union all
(select * from 
SC
where CId='02'
order by score
limit 2)
union all
(select * from 
SC
where CId='03'
order by score
limit 2);
42.统计每⻔课程的学⽣选修⼈数(超过 5 ⼈的课程才统计)。
select Cid,count(1) as num from
SC
group by 
Cid
having num >5
43.检索⾄少选修两⻔课程的学⽣学号
select SId,count(1) as num from
SC
group by 
SId
having num >= 2;
44.查询选修了全部课程的学⽣信息
select SId,count(1) as num from
SC
group by 
SId
having num = (select count(1) from Course);

45.查询各学⽣的年龄,只按年份来算
select *,year(now()) - year(Sage) as age from 
Student
46.查询各学⽣的年龄,按照出⽣⽇期来算,当前⽉⽇ < 出⽣年⽉的⽉⽇则,年龄减⼀
select 
*,
year(now()) - year(Sage) as age ,
case when date_format(now(),'%m-%d') < date_format(Sage,'%m-%d') then year(now()) - year(Sage) - 1 else year(now()) - year(Sage) end as age
from 
Student
47.查询本周过⽣⽇的学⽣
select * from 
Student
where week(concat(year(now()),'-',date_format(Sage,'%m-%d')) )=week(now()) ;
48.查询下周过⽣⽇的学⽣
select *from 
Student
where week(concat(year(now()),'-',date_format(Sage,'%m-%d')) ) =week(now())+1 ;
49.查询本⽉过⽣⽇的学⽣
select *from 
Student 
where month(concat(year(now()),'-',date_format(Sage,'%m-%d')) )=month(now()) ;
50.查询下⽉过⽣⽇的学⽣
select *from 
Student
where month(concat(year(now()),'-',date_format(Sage,'%m-%d')))=month(now()) +1;
posted @ 2024-09-12 20:52  李予桉  阅读(133)  评论(0编辑  收藏  举报