SQL语句执行顺序
(8) SELECT (9)DISTINCT<Select_list>
(1) FROM <left_table> (3) <join_type>JOIN<right_table>
(2) ON<join_condition>
(4) WHERE<where_condition>
(5) GROUP BY<group_by_list>
(6) WITH {CUBE|ROLLUP}
(7) HAVING<having_condtion>
(10) ORDER BY<order_by_list>
(11) LIMIT<limit_number>
9、查询所有课程成绩小于60分的同学的学号、姓名;成绩最大的小于60分,所以就是所有成绩小于60分
select t1.sid,sname
from
(select sid,max(score)
from SC group by sid having max(score)<60)as t1
left join student on t1.sid=student.sid
10、查询没有学全所有课的同学的学号、姓名;
select a.sid,sname
from
(select sid,count(cid) from SC
group by sid
having count(cid)<(select count(cid) from course))as a
left join student on a.sid=student.sid;
11、查询至少有一门课与学号为“01”的同学所学相同的同学的学号和姓名;
select sid,sname
from Student
where sid in
(select distinct sid #查询学生学号sid
from SC
where cid
in(select cid from SC where sid='01')) #在成绩表中查出学号为01的学生课程
and sid!='01';
12、查询和"01"号的同学学习的课程完全相同的其他同学的学号和姓名
注:课程完全相同≠课程数相同
注2:在同一次SQL语句中多次引用SC表,要对其进行a、b、c标注
select sid,sname
from Student #在student表中查出符合下面条件对应的学号和姓名
where sid
in
(SELECT
sid
from
(select * #查出所有课中和01重合的课
from SC as a
where cid
in
(select cid from SC where sid='01'))b #01学过的课
group by sid
having count(cid)=(select count(cid) FROM SC as c where sid='01')) #按学号分组后筛选出和01的学的课程数相等的学号
and sid!='01' #查出学号姓名后排除掉01本身
13、把“SC”表中“张三”老师教的课的成绩都更改为此课程的平均成绩;
暂跳过update题目
14、查询没学过"张三"老师讲授的任一门课程的学生姓名
select sname
from Student
where sid
not in(select distinct sid #not in 不在***里
from SC
left join course on
SC.cid=course.cid
left join teacher on
course.tid=teacher.tid
where tname='张三')
15、查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩
select t.sid,sname,avg_score #对子查询引用
from
(
select sid,count(if(score<60,cid,null)),avg(score)as avg_score #这里的自查询要对平均数avg(score)重命名,因为下一步的查询要对其引用
from SC
group by sid
having count(if(score<60,cid,null))>=2
)t
left join student
on t.sid=student.sid
16、检索"01"课程分数小于60,按分数降序排列的学生信息
select *
from
(select student.sid,sname,sage,ssex,cid,score
FROM student left join SC on student.sid=SC.sid
where cid='01' and score<60)t
order by score desc
17、按平均成绩从高到低显示所有学生的平均成绩
select sid,avg(score)as avg_score
from SC
group by sid
order by avg_score desc
18、查询各科成绩最高分、最低分和平均分,以如下形式显示:
以如下形式显示:课程 ID,课程 name,最高分,最低分,平均分,及格率,中等率,
优良率,优秀率
及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
select t.cid,any_value(cname)as 课程名称,max(score)as 最高分,
min(score)as 最低分,avg(score) as 平均分,
sum(及格)/count(sid) 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)t
left join course on t.cid=course.cid
group by cid
order by cid
19、按各科平均成绩从低到高和及格率的百分数从高到低顺序
select cid,avg(score) as avg_score,
count(if(score>=60,sid,null))/count(sid) as pass_rate
from SC
GROUP BY(cid) order by avg(score),pass_rate
20、查询学生的总成绩并进行排名
select sid,sum(score)
from SC
group by (sid)
order by sum(score) desc
21、查询不同老师所教不同课程平均分从高到低显示
select course.tid,SC.cid,avg(score)as avg_score
from course left join SC on course.cid=SC.cid
group by tid,cid
order by avg(score) desc
22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
select cid,sid,score
from
(select cid,sid,score,
row_number() over(partition by cid order by score desc)as ranking
from SC)c
where ranking>=2 and ranking<=3
23、统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比
#注意case when 前用sum求和,表示满足条件的人数的求和,而不是计次!!
select SC.cid,cname,
concat(round(100*sum(case when score between 85 and 100 then 1 else 0 end)/count(sid),2),'%') as '[100-85]',
concat(round(100*sum(case when score between 70 and 85 then 1 else 0 end)/count(sid),2),'%') as '[85-70]',
concat(round(100*sum(case when score between 60 and 70 then 1 else 0 end)/count(sid),2),'%') as '[70-60]',
concat(round(100*sum(case when score<=60 then 1 else 0 end)/count(sid),2),'%') as '[0-60]'
from SC left join course on SC.cid=course.cid
GROUP BY SC.cid,cname
24、查询学生平均成绩及其名次
select sid,avg_score,row_number() over(order by avg_score desc)as ranking
from (SELECT sid,avg(score)as avg_score from SC group by sid order by avg_score desc)a
25、查询各科成绩前三名的记录
select *
from
(select cid,score,row_number() over(partition by cid order by score desc)as rankk
from SC)a where rankk<=3
26、查询每门课程被选修的学生数
select cid,count(sid)as 人数
from SC
group by cid
27、查询出只选修了一门课程的全部学生的学号和姓名
select sid
from
(select sid,count(cid)as 选课数
from SC
group by sid)a
where 选课数=1
28、查询男生、女生人数
select ssex,count(distinct sid)as 人数
from student
group by ssex
29、查询名字中含有"风"字的学生信息
select *
from Student
where sname like "%风"
30、查询同名同性学生名单,并统计同名人数
select sname,ssex,count(sid)
from Student
group by ssex,sname
having count(sid)>=2
- 有关时间序列的查询
31、查询1990年出生的学生名单(注:Student表中Sage列的类型是datetime)
select * from student where year(sage)='1990'
32、查询每门课程的平均成绩,结果按平均成绩升序排列,平均成绩相同时,按课程号降序排列
select cid,avg(score)as avg_score
from SC
group by cid
order by avg_score,cid desc
33、成绩不重复,查询选修「张三」老师所授课程的学生中,成绩最高的学生信息及其成绩
思路:四表连接,筛选出教师为张三的课的学生成绩,限制出排名第一的学生,取出学生信息
selectsc.sid,sname,cname,score
from sc
left join courseon sc.cid=course.cid
left join teacheron course.tid=teacher.tid
left join studenton sc.sid=student.sid
where tname='张三'
order by score desc
limit 1;
34、成绩有重复的情况下,查询选修「张三」老师所授课程的学生中,成绩最高的学生
思路:先查出张三老师对应的课程,学生的最高成绩,将此成绩作为子查询的筛选条件,进行四表连接的查询筛选
select student.*,score
from student inner join SC on student.sid=SC.sid
inner join course on SC.cid=course.cid
inner join teacher on course.tid=teacher.tid
where tname='张三' and score=
(select max(score)
from teacher inner join course on teacher.tid=course.tid
inner join SC on course.cid=SC.cid
where tname='张三')
由于创建的表格里面没有重复的成绩,所以返回结果没有发生变化
35、查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩
SELECT DISTINCT a.*
FROMsc AS a INNER JOIN sc AS b
WHERE a.score = b.score AND a.cid != b.cid ;
注:上述方法算出来的会包含课程相同,学号不同的情况,比如最后两行。所以题目叙述不严谨,课程不同成绩相同是指课程两两不同即可还是全部不能相同,这点没有指明。
36、查询每门成绩最好的前两名
窗口函数
rank:并列名次,占用下一名次位置
dense_rank:并列名次,不占用下一名次位置
row_number:不考虑并列名次
SELECT *
from
(select cid,sid,score,
rank() over(partition by cid order by score desc)as rankk
from SC)a
where rankk<=2
37、统计每门课程的学生选修人数(超过 5 人的课程才统计)
select cid,count(sid)
from SC
group by cid
having count(sid)>5
38、检索至少选修两门课程的学生学号
select sid,count(cid)
from SC
group by sid
having count(cid)>=2
39、查询选修了全部课程的学生信息
先计算出一共有多少门课程,作为子查询。对学号进行分组,分组限定条件为学的课程数和总课程数相等。
select SC.sid,any_value(sname),any_value(sage),any_value(ssex)
from SC left join student
on SC.sid=student.sid
group by SC.sid
having count(cid)=
(select count(distinct cid)
from SC)
40.查询各学生的年龄,只按年份来算
select sid,year(now())-year(sage) as 年龄 #年份相减,四舍五入
from student
41.查询本周过生日的学生
select sid,sname
from student
where week(now())=week(sage)
43. 查询下周过生日的学生
select sid,sname
from student
where week(now())+1=week(sage)
44、查询本月过生日的学生
select sid,sname
from student
where month(sage)=month(now())
45、查询下月过生日的学生
select sid,sname
from student
where month(sage)=month(now())+1