SQL經典50題


用到的表的介紹

student: sid(學生ID),sname(學生姓名),sage,ssex
course: cid(課程ID),cname,tid(教師ID)
teacher: tid,tname
sc:sid,cid,score

 

只是附上題目和代碼,沒有運行結果

1.查詢"01"課程比"02"課程成績高的學生的信息及課程分數
select *
from 
    (select t1.sid,class1,class2
    from
        (select sid,score as class1 from sc where cid='01' )as t1
    join
        (select sid,score as class2 from sc where cid='02') as t2
    on t1.sid=t2.sid and t1.class1>t2.class2
    )r
left join student
on r.sid=student.sid 
;

1.1 查詢存在" 01 "課程但可能不存在" 02 "課程的情況(不存在時顯示為 null )
select *
from
    (select * from sc where cid='01')t1
left join
    (select * from sc where cid='02')t2
on t1.sid=t2.sid
;

1.2 查詢同時存在01和02課程的情況
select *
from
    (select * from sc where cid='01'
    )t1
join (select * from sc where cid='02'
    )t2
on t1.sid =t2.sid
;

1.3 查詢選擇了02課程但沒有01課程的情況
select * from sc where cid='02' and sid not in (
            select sid from sc where cid='01')
;

2.查詢平均成績大於等於 60 分的同學的學生編號和學生姓名和平均成績
select t1.sid,t1.meanscore,student.sname
from 
    (select sid,avg(score)as meanscore
     from sc 
     group by sid
     having avg(score)>=60
    )t1
left join student
on t1.sid=student.sid
;

3.查詢在 SC 表存在成績的學生信息
select distinct student.*
from sc 
join student
on sc.sid=student.sid
;

4.查詢所有同學的學生編號、學生姓名、選課總數、所有課程的成績總和
select r.*,student.sname
from 
    (select sid, count(distinct cid) as qcourse,sum(score)as sumscore
     from sc 
     group by sid 
    )r
left join student
on r.sid=student.sid
;


5.查詢「李」姓老師的數量
select count(*) from teacher where tname like ('李%')
;

6.查詢學過「張三」老師授課的同學的信息
select student.*
from 
    (select * from teacher where tname= '張三'
    )t1
left join course 
on t1.tid=course.tid
left join sc 
on course.cid=sc.cid
left join student
on sc.sid=student.sid
;

@7.查詢沒有學全所有課程的同學的信息
select student.*,qcourse
from 
    (select sid,count(distinct cid) as qcourse
    from sc 
    group by sid
    having count(distinct cid)<(select count(distinct cid) from course)
    )
left join student
on sc.sid=student.sid
;

@8.查詢至少有一門課與學號為" 01 "的同學所學相同的同學的信息
select student.*
from sc
join student
on sc.sid=student.sid
where sc.cid in (select cid from sc where sid ='01'
                    )
    and sc.sid !='01'
group by sc.sid
;

@9.查詢和" 01 "號的同學學習的課程完全相同的其他同學的信息

10.查詢沒學過"張三"老師講授的任一門課程的學生姓名
select sname
from student
where sid not in(select sid from sc 
                 left join course 
                 on sc.cid=course.cid
                 left join teacher
                 on course.tid=teacher.tid
                 where teacher.tname !='張三')
;

11.查詢兩門及其以上不及格課程的同學的學號,姓名及其平均成績
select t1.*,student.sname
from
    (select sid,avg(score)as meanscore
    from sc
    where sid in (select sid,count(distinct cid)
              from sc
              where score<60
              group by sid
              having count(distinct cid)>=2)
    )t1
left join student
on t1.sid=student.sid
;

12.檢索" 01 "課程分數小於 60,按分數降序排列的學生信息
select student.*,t1.score
from 
    (select *
    from sc
    where cid='01'
        and score<60
    )t1
left join student
on t1.sid=student.sid
order by t1.score desc
;

13.按平均成績從高到低顯示所有學生的所有課程的成績以及平均成績
select sc.*,t1.meanscore
from sc
left join
    (select sid,avg(score) as meanscore
    from sc 
    group by cid
    )t1
on sc.sid=t1.sid
order by t1.meanscore
;

14.查詢各科成績最高分、最低分和平均分,以如下形式顯示:
課程 ID,課程 name,最高分,最低分,平均分,及格率,中等率,優良率,優秀率
及格為>=60,中等為:70-80,優良為:80-90,優秀為:>=90
要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序
排列
select cid as '課程 ID',
        count(sid) as '課程人數',
        max(score) as '最高分',
        min(score) as '最低分',
        avg(score) as '平均分',
        cast(cast sum(及格) as double)/(cast count(sid) as double) as '及格率',
        SUM(中等) / COUNT(sid) AS '中等率',
        SUM(優良) / COUNT(sid) AS '優良率',
        SUM(優秀) / COUNT(sid) AS '優秀率'
from 
    (select *,
            case when score >=60 then 1 else 0 end as '及格',
            case when score>=70 and score<80 then 1 else 0 end as '中等 ',
            case when score >=80 and score<90 then 1 else 0 end as '優良',
            case when score >=90 then 1 else 0 end as '優秀'
    from sc
    )a 
group by cid
order by count(sid)desc,cid
;

@15.按各科成績進行排序,並顯示排名, Score 重復時保留名次空缺
select a.*,count(a.score) as '排名'
from sc a
left join sc b
on a.sid=b.sid
    and a.score < b.score
group by a.cid,a.sid,a.score
order by a.cid
;
--用sc中的score和自己進行對比,來計算“比當前分數高的分數有幾個”。

@15.1 按各科成績進行行排序,並顯示排名, Score 重復時合並名次
select a.*,count(b.score)+1 as '排名'
from sc a
left join sc b
on a.sid=b.sid
    and a.score < b.score
group by a.cid,a.sid,a.score
order by a.cid
;

@16.查詢學生的總成績,並進行排名,總分重復時保留名次空缺
select a.*,@rank:=@rank+1 as rank 
from 
    (select sid,
            sum(score)
    from sc
    group by sid
    order by sum(score)desc
    )a,
    (select @rank:=0
    )b 
;

17. 統計各科成績各分數段人數:課程編號,課程名稱,[100-85][85-70][70-60][60-0] 及所占百分比
select a.*,course.cname
from
    (select cid,
            sum(case when score>=85 and score <=100 then 1 else 0 end )/count(distinct sid) as '[100-85]',
            sum(case when score>=70 and score <85 then 1 else 0 end )/count(distinct sid) as '[85-75]',
            sum(case when score>=60 and score <70 then 1 else 0 end )/count(distinct sid) as '[70-60]',
            sum(case when score <60 then 1 else 0 end )/count(distinct sid) as '[60-0]'
    from sc 
    group by cid
    )a
left join course
on a.cid =course.cid
;

18.查詢各科成績前三名的記錄
select a.*,count(b.score)+1 as ranking
from sc as a
left join sc as b
on a.cid=b.cid and a.score<b.score
group by a.cid,a.sid 
having ranking <=3
order by a.cid,ranking
--having where不能使用別名,group by order by中可以使用別名
--
select *
from
    (select *,row_number()over(partition by cid order by score desc)as ranking 
    from sc)
where ranking>=3
;

19.查詢每門課程被選修的學生數
select cid,count(distinct sid) as num
from sc 
group by cid 
;

20.查詢出只選修兩門課程的學生學號和姓名
select sc.sid,student.sname
from sc
left join student
on sc.sid=student.sid
group by sc.cid
having count(cid)=2
;

21. 查詢男生、女生人數
select count(case when ssex='' then sid else null end)as '男生人數',
        count(case when ssex='' then sid else null end)as '女生人數'
from student
;

22. 查詢名字中含有「風」字的學生信息
select *
from student
where sname like '%風%'
;

23查詢同名同性學生名單,並統計同名人數
select sname,count(ssex)
from student
group by sname
having count(ssex)>1
;

24.查詢 1990 年出生的學生名單
select *
from student
where year(sage) like'1990%'
;

25.查詢每門課程的平均成績,結果按平均成績降序排列,平均成績相同時,按課程編號升序排列
select cid,avg(score)as meanscore
from sc 
group by cid
order by meanscore desc,cid
;

26.查詢平均成績大於等於 85 的所有學生的學號、姓名和平均成績
select a.sid,student.sname,a.meanscore
from 
    (select sid,avg(score) as meanscore
    from sc 
    group by sid
    having avg(score)>=85
    )a
left join student
on a.sid=student.sid
;

27.查詢課程名稱為「數學」,且分數低於 60 的學生姓名和分數
select student.sname,b.socre
from
    (select cid
    from course
    where cname ='數學'
    )a
left join 
    (select *
    from sc
    where score<60
    )b
on a.cid=b.cid
left join student
on b.sid=student.sid
;

28. 查詢所有學生的課程及分數情況(存在學生沒成績,沒選課的情況)
select sname,sc.cid,sc.score
from sc
join student
on sc.sid=student.sid
;

29.查詢任何一門課程成績在 70 分以上的姓名、課程名稱和分數
select sname,sc.cid,sc.score
from sc
join student
on sc.sid=student.sid
where sc.score >70
;

30.查詢不及格的課程
select distinct cid
from sc 
where score<60
;

31.查詢課程編號為 01 且課程成績在 80 分以上的學生的學號和姓名
select sc.sid,sname
from
    (select *
    from sc 
    where cid='01'and score>80
    )a 
left join student
on a.sid=student.sid
;

32.求每門課程的學生人數
select cid, count(sid)as cnt
from sc
group by cid
;

33.成績不重復,查詢選修「張三」老師所授課程的學生中,成績最高的學生信息及其成績
select student.*,sc.score
from
    (select tid
    from teacher
    where tname='張三'
    )a
left join course
on a.tid=course.tid
left join sc
on course.cid=sc.cid
left join student
on sc.sid=student.sid
order by sc.score desc
limit 1
;

34.成績有重復的情況下,查詢選修「張三」老師所授課程的學生中,成績最高的學生

35.查詢不同課程成績相同的學生的學生編號、課程編號、學生成績
select distinct a.*
from sc as a
join sc as b
on a.score=b.score 
    and a.cid!=b.cid
;


36. 查詢每門成績最好的前兩名
select *
from 
    (select *,
        row_number()over(partition by cid order by score desc)as ranking
    )
where ranking <=2
;
--方法2自交
select *
from sc
where (select count(*)
        from sc as a 
        where sc.cid=a.cid
            and sc.score<a.score
        )<2
order by cid ,sc.score desc
;

37. 統計每門課程的學生選修人數(超過 5 人的課程才統計)
select cid,count(sid)
from sc
group by sc
having count(sid)>5
;

38.檢索至少選修兩門課程的學生學號
select cid,count(sid)
from sc
group by sc
having count(sid)>2
;

39.查詢選修了全部課程的學生信息
select student.*
from
    (select sid
    from sc 
    where cid =(select count(distinct cid) from course 
                )
    )a 
left join student
on a.sid=student.sid
;

40.查詢各學生的年齡,只按年份來算
select sname,year(now())-year(age) as '年級'
from student
;

41. 按照出生日期來算,當前月日 < 出生年月的月日則,年齡減一
select sname,    
        case when (date_format(now(),'%m-%d')-date_format(sage,'%m-%d')<0 
        then year(now())-year(sage)+1
        else year(now())-year(sage)
        end as '年齡'
from student
;
--date_format轉化為時間戳,利用時間戳求差值

42.查詢本周過生日的學生
select * 
from student
where weekofyear(date_format(now(),'%y%m%d'))
        =
      weekofyear(date_format(sage,'%y%m%d')-date_format(sage,'%y')*10000+date_format(now(),'%y')*10000)
;
--出生日期的年份去掉,得到月份和日期,再拼接上當前的年份
--weekofyear函數是計算出當前日期所在周數


43. 查詢下周過生日的學生
select * 
from student
where weekofyear(date_format(now(),'%y%m%d'))+1
        =
      weekofyear(date_format(sage,'%y%m%d')-date_format(sage,'%y')*10000+date_format(now(),'%y')*10000)
;

44.查詢本月過生日的學生
select sname
from student
where month(sage)=month(now())
;

45.查詢下月過生日的學生
select sname
from student
where month(sage)=month(now())+1
;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM