50道SQL練習(xí)題及答案與詳細分析

網(wǎng)上流傳較廣的50道SQL訓(xùn)練,奮斗了不知道多久終于寫完了。前18道題的難度依次遞增锄禽,從19題開始的后半部分算是循環(huán)練習(xí)和額外function的附加練習(xí)疹蛉,難度恢復(fù)到普通狀態(tài)嘿般。
第9題非常難段标,我反正沒有寫出來,如果有寫出來了的朋友還請賜教炉奴。
這50道里面自認為應(yīng)該沒有太多錯誤逼庞,而且盡可能使用了最簡單或是最直接的查詢,有多種不相上下解法的題目我也都列出了瞻赶,但也歡迎一起學(xué)習(xí)的朋友進行討論和解法優(yōu)化啊~


數(shù)據(jù)表介紹

--1.學(xué)生表
Student(SId,Sname,Sage,Ssex)
--SId 學(xué)生編號,Sname 學(xué)生姓名,Sage 出生年月,Ssex 學(xué)生性別

--2.課程表
Course(CId,Cname,TId)
--CId 課程編號,Cname 課程名稱,TId 教師編號

--3.教師表
Teacher(TId,Tname)
--TId 教師編號,Tname 教師姓名

--4.成績表
SC(SId,CId,score)
--SId 學(xué)生編號,CId 課程編號,score 分數(shù)

學(xué)生表 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' , '孫風(fēng)' , '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' , '數(shù)學(xué)' , '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);

練習(xí)題目

  1. 查詢" 01 "課程比" 02 "課程成績高的學(xué)生的信息及課程分數(shù)

1.1 查詢同時存在" 01 "課程和" 02 "課程的情況

1.2 查詢存在" 01 "課程但可能不存在" 02 "課程的情況(不存在時顯示為 null )

1.3 查詢不存在" 01 "課程但存在" 02 "課程的情況

  1. 查詢平均成績大于等于 60 分的同學(xué)的學(xué)生編號和學(xué)生姓名和平均成績

  2. 查詢在 SC 表存在成績的學(xué)生信息

  3. 查詢所有同學(xué)的學(xué)生編號赛糟、學(xué)生姓名、選課總數(shù)砸逊、所有課程的總成績(沒成績的顯示為 null )

4.1 查有成績的學(xué)生信息

  1. 查詢「李」姓老師的數(shù)量

  2. 查詢學(xué)過「張三」老師授課的同學(xué)的信息

  3. 查詢沒有學(xué)全所有課程的同學(xué)的信息

  4. 查詢至少有一門課與學(xué)號為" 01 "的同學(xué)所學(xué)相同的同學(xué)的信息

  5. 查詢和" 01 "號的同學(xué)學(xué)習(xí)的課程 完全相同的其他同學(xué)的信息

  6. 查詢沒學(xué)過"張三"老師講授的任一門課程的學(xué)生姓名

  7. 查詢兩門及其以上不及格課程的同學(xué)的學(xué)號璧南,姓名及其平均成績

  8. 檢索" 01 "課程分數(shù)小于 60,按分數(shù)降序排列的學(xué)生信息

  9. 按平均成績從高到低顯示所有學(xué)生的所有課程的成績以及平均成績

  10. 查詢各科成績最高分师逸、最低分和平均分:

以如下形式顯示:課程 ID司倚,課程 name,最高分篓像,最低分对湃,平均分,及格率遗淳,中等率拍柒,優(yōu)良率,優(yōu)秀率

及格為>=60屈暗,中等為:70-80拆讯,優(yōu)良為:80-90,優(yōu)秀為:>=90

要求輸出課程號和選修人數(shù)养叛,查詢結(jié)果按人數(shù)降序排列种呐,若人數(shù)相同,按課程號升序排列

  1. 按各科成績進行排序弃甥,并顯示排名爽室, Score 重復(fù)時保留名次空缺

15.1 按各科成績進行排序,并顯示排名淆攻, Score 重復(fù)時合并名次

  1. 查詢學(xué)生的總成績阔墩,并進行排名,總分重復(fù)時保留名次空缺

16.1 查詢學(xué)生的總成績瓶珊,并進行排名啸箫,總分重復(fù)時不保留名次空缺

  1. 統(tǒng)計各科成績各分數(shù)段人數(shù):課程編號,課程名稱伞芹,[100-85]忘苛,[85-70]蝉娜,[70-60],[60-0] 及所占百分比

  2. 查詢各科成績前三名的記錄

  3. 查詢每門課程被選修的學(xué)生數(shù)

  4. 查詢出只選修兩門課程的學(xué)生學(xué)號和姓名

  5. 查詢男生扎唾、女生人數(shù)

  6. 查詢名字中含有「風(fēng)」字的學(xué)生信息

  7. 查詢同名同性學(xué)生名單召川,并統(tǒng)計同名人數(shù)

  8. 查詢 1990 年出生的學(xué)生名單

  9. 查詢每門課程的平均成績,結(jié)果按平均成績降序排列胸遇,平均成績相同時荧呐,按課程編號升序排列

  10. 查詢平均成績大于等于 85 的所有學(xué)生的學(xué)號、姓名和平均成績

  11. 查詢課程名稱為「數(shù)學(xué)」狐榔,且分數(shù)低于 60 的學(xué)生姓名和分數(shù)

  12. 查詢所有學(xué)生的課程及分數(shù)情況(存在學(xué)生沒成績坛增,沒選課的情況)

  13. 查詢?nèi)魏我婚T課程成績在 70 分以上的姓名获雕、課程名稱和分數(shù)

  14. 查詢不及格的課程

  15. 查詢課程編號為 01 且課程成績在 80 分以上的學(xué)生的學(xué)號和姓名

  16. 求每門課程的學(xué)生人數(shù)

  17. 成績不重復(fù)薄腻,查詢選修「張三」老師所授課程的學(xué)生中,成績最高的學(xué)生信息及其成績

  18. 成績有重復(fù)的情況下届案,查詢選修「張三」老師所授課程的學(xué)生中庵楷,成績最高的學(xué)生信息及其成績

  19. 查詢不同課程成績相同的學(xué)生的學(xué)生編號、課程編號楣颠、學(xué)生成績

  20. 查詢每門功成績最好的前兩名

  21. 統(tǒng)計每門課程的學(xué)生選修人數(shù)(超過 5 人的課程才統(tǒng)計)尽纽。

  22. 檢索至少選修兩門課程的學(xué)生學(xué)號

  23. 查詢選修了全部課程的學(xué)生信息

  24. 查詢各學(xué)生的年齡,只按年份來算

  25. 按照出生日期來算童漩,當(dāng)前月日 < 出生年月的月日則弄贿,年齡減一

  26. 查詢本周過生日的學(xué)生

  27. 查詢下周過生日的學(xué)生

  28. 查詢本月過生日的學(xué)生

  29. 查詢下月過生日的學(xué)生

答案


1.查詢" 01 "課程比" 02 "課程成績高的學(xué)生的信息及課程分數(shù)
因為需要全部的學(xué)生信息,則需要在sc表中得到符合條件的SId后與student表進行join矫膨,可以left join 也可以 right join

select * from Student RIGHT JOIN (
    select t1.SId, class1, class2 from
          (select SId, score as class1 from sc where sc.CId = '01')as t1, 
          (select SId, score as class2 from sc where sc.CId = '02')as t2
    where t1.SId = t2.SId AND t1.class1 > t2.class2
)r 
on Student.SId = r.SId;
select * from  (
    select t1.SId, class1, class2 
    from
        (SELECT SId, score as class1 FROM sc WHERE sc.CId = '01') AS t1, 
        (SELECT SId, score as class2 FROM sc WHERE sc.CId = '02') AS t2
    where t1.SId = t2.SId and t1.class1 > t2.class2
) r 
LEFT JOIN Student
ON Student.SId = r.SId;

1.1 查詢同時存在" 01 "課程和" 02 "課程的情況

select * from 
    (select * from sc where sc.CId = '01') as t1, 
    (select * from sc where sc.CId = '02') as t2
where t1.SId = t2.SId;

1.2 查詢存在" 01 "課程但可能不存在" 02 "課程的情況(不存在時顯示為 null )
這一道就是明顯需要使用join的情況了差凹,02可能不存在,即為left join的右側(cè)或right join 的左側(cè)即可.

select * from 
(select * from sc where sc.CId = '01') as t1
left join 
(select * from sc where sc.CId = '02') as t2
on t1.SId = t2.SId;
select * from 
(select * from sc where sc.CId = '02') as t2
right join 
(select * from sc where sc.CId = '01') as t1
on t1.SId = t2.SId;

1.3 查詢不存在" 01 "課程但存在" 02 "課程的情況

select * from sc
where sc.SId not in (
    select SId from sc 
    where sc.CId = '01'
) 
AND sc.CId= '02';
  1. 查詢平均成績大于等于 60 分的同學(xué)的學(xué)生編號和學(xué)生姓名和平均成績
    這里只用根據(jù)學(xué)生ID把成績分組侧馅,對分組中的score求平均值危尿,最后在選取結(jié)果中AVG大于60的即可. 注意,這里必須要給計算得到的AVG結(jié)果一個alias.(AS ss)
    得到學(xué)生信息的時候既可以用join也可以用一般的聯(lián)合搜索
select student.SId,sname,ss from student,(
    select SId, AVG(score) as ss from sc  
    GROUP BY SId 
    HAVING AVG(score)> 60
    )r
where student.sid = r.sid;
select Student.SId, Student.Sname, r.ss from Student right join(
      select SId, AVG(score) AS ss from sc
      GROUP BY SId
      HAVING AVG(score)> 60
)r on Student.SId = r.SId;
select s.SId,ss,Sname from(
select SId, AVG(score) as ss from sc  
GROUP BY SId 
HAVING AVG(score)> 60
)r left join 
(select Student.SId, Student.Sname from
Student)s on s.SId = r.SId;
  1. 查詢在 SC 表存在成績的學(xué)生信息
select DISTINCT student.*
from student,sc
where student.SId=sc.SId

4.查詢所有同學(xué)的學(xué)生編號馁痴、學(xué)生姓名谊娇、選課總數(shù)、所有課程的成績總和
聯(lián)合查詢不會顯示沒選課的學(xué)生:

select student.sid, student.sname,r.coursenumber,r.scoresum
from student,
(select sc.sid, sum(sc.score) as scoresum, count(sc.cid) as coursenumber from sc 
group by sc.sid)r
where student.sid = r.sid;

如要顯示沒選課的學(xué)生(顯示為NULL)罗晕,需要使用join:

select s.sid, s.sname,r.coursenumber,r.scoresum
from (
    (select student.sid,student.sname 
    from student
    )s 
    left join 
    (select 
        sc.sid, sum(sc.score) as scoresum, count(sc.cid) as coursenumber
        from sc 
        group by sc.sid
    )r 
   on s.sid = r.sid
);

4.1 查有成績的學(xué)生信息
這一題涉及到in和exists的用法济欢,在這種小表中,兩種方法的效率都差不多小渊,但是請參考SQL查詢中in和exists的區(qū)別分析
當(dāng)表2的記錄數(shù)量非常大的時候船逮,選用exists比in要高效很多.
EXISTS用于檢查子查詢是否至少會返回一行數(shù)據(jù),該子查詢實際上并不返回任何數(shù)據(jù)粤铭,而是返回值True或False.
結(jié)論:IN()適合B表比A表數(shù)據(jù)小的情況
結(jié)論:EXISTS()適合B表比A表數(shù)據(jù)大的情況

select * from student 
where exists (select sc.sid from sc where student.sid = sc.sid);
select * from student
where student.sid in (select sc.sid from sc);
  1. 查詢「李」姓老師的數(shù)量
select count(*)
from teacher
where tname like '李%';
  1. 查詢學(xué)過「張三」老師授課的同學(xué)的信息
    多表聯(lián)合查詢
select student.* from student,teacher,course,sc
where 
    student.sid = sc.sid 
    and course.cid=sc.cid 
    and course.tid = teacher.tid 
    and tname = '張三';
  1. 查詢沒有學(xué)全所有課程的同學(xué)的信息
    因為有學(xué)生什么課都沒有選挖胃,反向思考,先查詢選了所有課的學(xué)生,再選擇這些人之外的學(xué)生.
select * from student
where student.sid not in (
  select sc.sid from sc
  group by sc.sid
  having count(sc.cid)= (select count(cid) from course)
);
  1. 查詢至少有一門課與學(xué)號為" 01 "的同學(xué)所學(xué)相同的同學(xué)的信息
    這個用聯(lián)合查詢也可以酱鸭,但是邏輯不清楚吗垮,我覺得較為清楚的邏輯是這樣的:從sc表查詢01同學(xué)的所有選課cid--從sc表查詢所有同學(xué)的sid如果其cid在前面的結(jié)果中--從student表查詢所有學(xué)生信息如果sid在前面的結(jié)果中
select * from student 
where student.sid in (
    select sc.sid from sc 
    where sc.cid in(
        select sc.cid from sc 
        where sc.sid = '01'
    )
);

9.查詢和" 01 "號的同學(xué)學(xué)習(xí)的課程完全相同的其他同學(xué)的信息
不會做。

10.查詢沒學(xué)過"張三"老師講授的任一門課程的學(xué)生姓名
仍然還是嵌套凹髓,三層嵌套烁登, 或者多表聯(lián)合查詢

select * from student
    where student.sid not in(
        select sc.sid from sc where sc.cid in(
            select course.cid from course where course.tid in(
                select teacher.tid from teacher where tname = "張三"
            )
        )
    );
select * from student
where student.sid not in(
    select sc.sid from sc,course,teacher 
    where
        sc.cid = course.cid
        and course.tid = teacher.tid
        and teacher.tname= "張三"
);

11.查詢兩門及其以上不及格課程的同學(xué)的學(xué)號,姓名及其平均成績
從SC表中選取score小于60的蔚舀,并group by sid饵沧,having count 大于1
(更新采用評論1中的解法)

select student.SId, student.Sname,b.avg
from student RIGHT JOIN
(select sid, AVG(score) as avg from sc
    where sid in (
              select sid from sc 
              where score<60 
              GROUP BY sid 
              HAVING count(score)>1)
    GROUP BY sid) b on student.sid=b.sid;
  1. 檢索" 01 "課程分數(shù)小于 60,按分數(shù)降序排列的學(xué)生信息
    雙表聯(lián)合查詢赌躺,在查詢最后可以設(shè)置排序方式狼牺,語法為ORDER BY ***** DESC\ASC;
select student.*, sc.score from student, sc
where student.sid = sc.sid
and sc.score < 60
and cid = "01"
ORDER BY sc.score DESC;
  1. 按平均成績從高到低顯示所有學(xué)生的所有課程的成績以及平均成績
select *  from sc 
left join (
    select sid,avg(score) as avscore from sc 
    group by sid
    )r 
on sc.sid = r.sid
order by avscore desc;
  1. 查詢各科成績最高分、最低分和平均分:

以如下形式顯示:課程 ID礼患,課程 name是钥,最高分,最低分缅叠,平均分悄泥,及格率,中等率肤粱,優(yōu)良率弹囚,優(yōu)秀率

及格為>=60,中等為:70-80领曼,優(yōu)良為:80-90鸥鹉,優(yōu)秀為:>=90

要求輸出課程號和選修人數(shù),查詢結(jié)果按人數(shù)降序排列悯森,若人數(shù)相同宋舷,按課程號升序排列

select 
sc.CId ,
max(sc.score)as 最高分,
min(sc.score)as 最低分,
AVG(sc.score)as 平均分,
count(*)as 選修人數(shù),
sum(case when sc.score>=60 then 1 else 0 end )/count(*)as 及格率,
sum(case when sc.score>=70 and sc.score<80 then 1 else 0 end )/count(*)as 中等率,
sum(case when sc.score>=80 and sc.score<90 then 1 else 0 end )/count(*)as 優(yōu)良率,
sum(case when sc.score>=90 then 1 else 0 end )/count(*)as 優(yōu)秀率 
from sc
GROUP BY sc.CId
ORDER BY count(*)DESC, sc.CId ASC
  1. 按各科成績進行排序,并顯示排名瓢姻, Score 重復(fù)時保留名次空缺
    這一道題有點tricky祝蝠,可以用變量,但也有更為簡單的方法幻碱,即自交(左交)
    用sc中的score和自己進行對比绎狭,來計算“比當(dāng)前分數(shù)高的分數(shù)有幾個”。
select a.cid, a.sid, a.score, count(b.score)+1 as rank
from sc as a 
left join sc as b 
on a.score<b.score and a.cid = b.cid
group by a.cid, a.sid,a.score
order by a.cid, rank ASC;
  1. 查詢學(xué)生的總成績褥傍,并進行排名儡嘶,總分重復(fù)時不保留名次空缺
    這里主要學(xué)習(xí)一下使用變量。在SQL里面變量用@來標識恍风。
set @crank=0;
select q.sid, total, @crank := @crank +1 as rank from(
select sc.sid, sum(sc.score) as total from sc
group by sc.sid
order by total desc)q;
  1. 統(tǒng)計各科成績各分數(shù)段人數(shù):課程編號蹦狂,課程名稱誓篱,[100-85],[85-70]凯楔,[70-60]窜骄,[60-0] 及所占百分比
    有時候覺得自己真是死腦筋。group by以后的查詢結(jié)果無法使用別名摆屯,所以不要想著先單表group by計算出結(jié)果再從第二張表里添上課程信息邻遏,而應(yīng)該先將兩張表join在一起得到所有想要的屬性再對這張總表進行統(tǒng)計計算。這里就不算百分比了虐骑,道理相同准验。
    注意一下,用case when 返回1 以后的統(tǒng)計不是用count而是sum
select course.cname, course.cid,
sum(case when sc.score<=100 and sc.score>85 then 1 else 0 end) as "[100-85]",
sum(case when sc.score<=85 and sc.score>70 then 1 else 0 end) as "[85-70]",
sum(case when sc.score<=70 and sc.score>60 then 1 else 0 end) as "[70-60]",
sum(case when sc.score<=60 and sc.score>0 then 1 else 0 end) as "[60-0]"
from sc left join course
on sc.cid = course.cid
group by sc.cid;
  1. 查詢各科成績前三名的記錄
    大坑比廷没。mysql不能group by 了以后取limit糊饱,所以不要想著討巧了,我快被這一題氣死了腕柜。思路有兩種济似,第一種比較暴力矫废,計算比自己分數(shù)大的記錄有幾條盏缤,如果小于3 就select,因為對前三名來說不會有3個及以上的分數(shù)比自己大了蓖扑,最后再對所有select到的結(jié)果按照分數(shù)和課程編號排名即可唉铜。
select * from sc
where (
select count(*) from sc as a 
where sc.cid = a.cid and sc.score<a.score 
)< 3
order by cid asc, sc.score desc;

第二種比較靈巧一些,用自身左交律杠,但是有點難以理解潭流。
先用自己交自己,條件為a.cid = b.cid and a.score<b.score柜去,其實就是列出同一門課內(nèi)所有分數(shù)比較的情況灰嫉。
想要查看完整的表可以

select * from sc a 
left join sc b on a.cid = b.cid and a.score<b.score
order by a.cid,a.score;
結(jié)果

查看,發(fā)現(xiàn)結(jié)果是47行的一個表嗓奢,列出了類似 01號課里“30分小于50讼撒,也小于70,也小于80股耽,也小于90”“50分小于70根盒,小于80,小于90”.....
所以理論上物蝙,對任何一門課來說炎滞,分數(shù)最高的那三個記錄,在這張大表里诬乞,通過a.sid和a.cid可以聯(lián)合確定這個同學(xué)的這門課的這個分數(shù)究竟比多少個其他記錄高/低册赛,
如果這個特定的a.sid和a.cid組合出現(xiàn)在這張表里的次數(shù)少于3個钠导,那就意味著這個組合(學(xué)號+課號+分數(shù))是這門課里排名前三的。
所以下面這個計算中having count 部分其實count()或者任意其他列都可以森瘪,這里制定了一個列只是因為比count()運行速度上更快辈双。

select a.sid,a.cid,a.score from sc a 
left join sc b on a.cid = b.cid and a.score<b.score
group by a.cid, a.sid
having count(b.cid)<3
order by a.cid;
  1. 查詢每門課程被選修的學(xué)生數(shù)
select cid, count(sid) from sc 
group by cid;
  1. 查詢出只選修兩門課程的學(xué)生學(xué)號和姓名
    嵌套查詢
select student.sid, student.sname from student
where student.sid in
(select sc.sid from sc
group by sc.sid
having count(sc.cid)=2
);

聯(lián)合查詢

select student.SId,student.Sname
from sc,student
where student.SId=sc.SId  
GROUP BY sc.SId
HAVING count(*)=2;

21.查詢男生柜砾、女生人數(shù)

select ssex, count(*) from student
group by ssex;
  1. 查詢名字中含有「風(fēng)」字的學(xué)生信息
select *
from student 
where student.Sname like '%風(fēng)%'

23.查詢同名學(xué)生名單湃望,并統(tǒng)計同名人數(shù)
找到同名的名字并統(tǒng)計個數(shù)

select sname, count(*) from student
group by sname
having count(*)>1;

嵌套查詢列出同名的全部學(xué)生的信息

select * from student
where sname in (
select sname from student
group by sname
having count(*)>1
);

24.查詢 1990 年出生的學(xué)生名單

select *
from student
where YEAR(student.Sage)=1990;

25.查詢每門課程的平均成績,結(jié)果按平均成績降序排列痰驱,平均成績相同時证芭,按課程編號升序排列

select sc.cid, course.cname, AVG(SC.SCORE) as average from sc, course
where sc.cid = course.cid
group by sc.cid 
order by average desc,cid asc;

26.查詢平均成績大于等于 85 的所有學(xué)生的學(xué)號、姓名和平均成績
having也可以用來截取結(jié)果表担映,在這里就先得到平均成績總表废士,再截取AVG大于85的即可.

select student.sid, student.sname, AVG(sc.score) as aver from student, sc
where student.sid = sc.sid
group by sc.sid
having aver > 85;
  1. 查詢課程名稱為「數(shù)學(xué)」,且分數(shù)低于 60 的學(xué)生姓名和分數(shù)
select student.sname, sc.score from student, sc, course
where student.sid = sc.sid
and course.cid = sc.cid
and course.cname = "數(shù)學(xué)"
and sc.score < 60;
  1. 查詢所有學(xué)生的課程及分數(shù)情況(存在學(xué)生沒成績蝇完,沒選課的情況)
select student.sname, cid, score from student
left join sc
on student.sid = sc.sid;
  1. 查詢?nèi)魏我婚T課程成績在 70 分以上的姓名官硝、課程名稱和分數(shù)
select student.sname, course.cname,sc.score from student,course,sc
where sc.score>70
and student.sid = sc.sid
and sc.cid = course.cid;

30.查詢存在不及格的課程
可以用group by 來取唯一,也可以用distinct

select cid from sc
where score< 60
group by cid;
select DISTINCT sc.CId
from sc
where sc.score <60;

31.查詢課程編號為 01 且課程成績在 80 分及以上的學(xué)生的學(xué)號和姓名

select student.sid,student.sname 
from student,sc
where cid="01"
and score>=80
and student.sid = sc.sid;
  1. 求每門課程的學(xué)生人數(shù)
select sc.CId,count(*) as 學(xué)生人數(shù)
from sc
GROUP BY sc.CId;
  1. 成績不重復(fù)短蜕,查詢選修「張三」老師所授課程的學(xué)生中氢架,成績最高的學(xué)生信息及其成績
    用having max()理論上也是對的,但是下面那種按分數(shù)排序然后取limit 1的更直觀可靠
select student.*, sc.score, sc.cid from student, teacher, course,sc 
where teacher.tid = course.tid
and sc.sid = student.sid
and sc.cid = course.cid
and teacher.tname = "張三"
having max(sc.score);
select student.*, sc.score, sc.cid from student, teacher, course,sc 
where teacher.tid = course.tid
and sc.sid = student.sid
and sc.cid = course.cid
and teacher.tname = "張三"
order by score desc
limit 1;
  1. 成績有重復(fù)的情況下朋魔,查詢選修「張三」老師所授課程的學(xué)生中岖研,成績最高的學(xué)生信息及其成績
    為了驗證這一題,先修改原始數(shù)據(jù)
UPDATE sc SET score=90
where sid = "07"
and cid ="02";

這樣張三老師教的02號課就有兩個學(xué)生同時獲得90的最高分了警检。
這道題的思路繼續(xù)上一題孙援,我們已經(jīng)查詢到了符合限定條件的最高分了,這個時候只用比較這張表扇雕,找到全部score等于這個最高分的記錄就可拓售,看起來有點繁復(fù)。

select student.*, sc.score, sc.cid from student, teacher, course,sc 
where teacher.tid = course.tid
and sc.sid = student.sid
and sc.cid = course.cid
and teacher.tname = "張三"
and sc.score = (
    select Max(sc.score) 
    from sc,student, teacher, course
    where teacher.tid = course.tid
    and sc.sid = student.sid
    and sc.cid = course.cid
    and teacher.tname = "張三"
);
  1. 查詢不同課程成績相同的學(xué)生的學(xué)生編號镶奉、課程編號础淤、學(xué)生成績
    同上,在這里用了inner join后會有概念是重復(fù)的記錄:“01 課與 03課”=“03 課與 01 課”腮鞍,所以這里取唯一可以直接用group by
select  a.cid, a.sid,  a.score from sc as a
inner join 
sc as b
on a.sid = b.sid
and a.cid != b.cid
and a.score = b.score
group by cid, sid;

36.查詢每門功成績最好的前兩名
同上19題

select a.sid,a.cid,a.score 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 count(b.cid)<2
order by a.cid;

37.統(tǒng)計每門課程的學(xué)生選修人數(shù)(超過 5 人的課程才統(tǒng)計)

select sc.cid, count(sid) as cc from sc
group by cid
having cc >5;

38.檢索至少選修兩門課程的學(xué)生學(xué)號

select sid, count(cid) as cc from sc
group by sid
having cc>=2;
  1. 查詢選修了全部課程的學(xué)生信息
select student.*
from sc ,student 
where sc.SId=student.SId
GROUP BY sc.SId
HAVING count(*) = (select DISTINCT count(*) from course )

40.查詢各學(xué)生的年齡值骇,只按年份來算
不想做,一般都用41題的方法精確到天


  1. 按照出生日期來算移国,當(dāng)前月日 < 出生年月的月日則吱瘩,年齡減一
select student.SId as 學(xué)生編號,student.Sname  as  學(xué)生姓名,
TIMESTAMPDIFF(YEAR,student.Sage,CURDATE()) as 學(xué)生年齡
from student

42.查詢本周過生日的學(xué)生

select *
from student 
where WEEKOFYEAR(student.Sage)=WEEKOFYEAR(CURDATE());
  1. 查詢下周過生日的學(xué)生
select *
from student 
where WEEKOFYEAR(student.Sage)=WEEKOFYEAR(CURDATE())+1;

44.查詢本月過生日的學(xué)生

select *
from student 
where MONTH(student.Sage)=MONTH(CURDATE());

45.查詢下月過生日的學(xué)生

select *
from student 
where MONTH(student.Sage)=MONTH(CURDATE())+1;
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市迹缀,隨后出現(xiàn)的幾起案子使碾,更是在濱河造成了極大的恐慌蜜徽,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件票摇,死亡現(xiàn)場離奇詭異拘鞋,居然都是意外死亡,警方通過查閱死者的電腦和手機矢门,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門盆色,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人祟剔,你說我怎么就攤上這事隔躲。” “怎么了物延?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵宣旱,是天一觀的道長。 經(jīng)常有香客問我叛薯,道長浑吟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任耗溜,我火速辦了婚禮组力,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘强霎。我一直安慰自己忿项,他們只是感情好蓉冈,可當(dāng)我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布城舞。 她就那樣靜靜地躺著,像睡著了一般寞酿。 火紅的嫁衣襯著肌膚如雪家夺。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天伐弹,我揣著相機與錄音拉馋,去河邊找鬼。 笑死惨好,一個胖子當(dāng)著我的面吹牛煌茴,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播日川,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼蔓腐,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了龄句?” 一聲冷哼從身側(cè)響起回论,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤散罕,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后傀蓉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體欧漱,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年葬燎,在試婚紗的時候發(fā)現(xiàn)自己被綠了误甚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡谱净,死狀恐怖靶草,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情岳遥,我是刑警寧澤奕翔,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布,位于F島的核電站浩蓉,受9級特大地震影響派继,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜捻艳,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一驾窟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧认轨,春花似錦绅络、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至纪蜒,卻和暖如春衷恭,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背纯续。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工随珠, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人猬错。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓窗看,卻偏偏與公主長得像,于是被迫代替她去往敵國和親倦炒。 傳聞我的和親對象是個殘疾皇子显沈,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容