Sql经典题目的mysql实现②

25、查询各科成绩前三名的记录(不考虑成绩并列情况):

select t1.s_id,t1.c_id,t1.s_score
from score t1
where exists
(
select count(1) from score
where t1.c_id = c_id
and t1.s_score < s_score
having count(1) < 3
)
order by t1.c_id,s_score desc;

26、查询每门课程被选修的学生数:

-- 思路: 成绩表有修的应该就有选
select c_id,count(s_id) from score group by c_id;
-- 27、查询出只选修一门课程的全部学生的学号和姓名:
select s.s_id,s_name ,count(s_score) from score s,student where s.s_id=student.s_id group by s_id having count(s_score) =1;

28、查询男生、女生人数:

select
sum(case when s.s_sex='男' then 1 else 0 end) as 男生人数,
sum(case when s.s_sex='女' then 1 else 0 end) as 女生人数
from student s;


select (case when s_sex='男' then '男' else '女' end) 性别,count(1) 人数 from student group by s_sex;

29、查询姓“李”的学生名单:

SELECT * FROM student s
WHERE s.s_name LIKE '李%';

30、查询同名同姓的学生名单,并统计同名人数:

select s_name,count(1) 人数 from student group by s_name having 人数 >1;

31、1981年出生的学生名单

(注:student表中sage列的类型是datetime)

select s_name,DATE_FORMAT(s_birth ,'%Y')as age from student_copy where DATE_FORMAT(s_birth ,'%Y')=1981;

32、查询平均成绩大于85的所有学生的学号、姓名和平均成绩:

select st.s_id,st.s_name,avg(s_score)as pjcj from score sc ,student st
where sc.s_id=st.s_id
group by sc.s_id
having pjcj>85 ;

33、查询每门课程的平均成绩

结果按平均成绩升序排序,平均成绩相同时,按课程号降序排列

select c_id, avg(s_score)as pjcj from score s
group by c_id
order by pjcj ,c_id desc;

34、查询课程名称为“语文”,且分数低于60的学生名字和分数:

select st.s_name,sc.s_score
from course c,score sc ,student st
where c.c_name='语文'
and sc.s_score<60
and c.c_id=sc.c_id
and sc.s_id=st.s_id;

35、查询所有学生的选课情况:

select st.s_name,c.c_name from course c,score sc ,student st
where st.s_id=sc.s_id
and sc.c_id=c.c_id
and sc.s_score is not NULL
order by s_name;

36、查询任何一门课程成绩在70分以上的姓名、课程名称和分数:

select st.s_id,s_name,c_name , sc.s_score
from course c,score sc,student st
where st.s_id=sc.s_id
and sc.c_id=c.c_id
and sc.s_score between 70 and 100
order by s_id;

37、查询课程和不及格人数,并按课程号从大到小的排列:

select c_id ,sum(case when s_score<60 then 1 else 0 end) as 不及格人数 from score group by c_id;

38、查询课程编号为“003”且课程成绩在80分以上的学生的学号和姓名

select sc.s_id,st.s_name,sc.s_score from score sc
left join student st on sc.s_id=st.s_id
where sc.c_id=03 and sc.s_score>=80

39、求选了课程的学生人数:

select count(distinct s_id) from score where s_score is not null ;

40 查询选修“叶平”老师所授课程的学生中,成绩最高的学生姓名及其成绩

select sc.s_id,st.s_name,sc.s_score
 from score sc,course c, teacher t,student st
where sc.c_id=c.c_id
and c.t_id=t.t_id
and t.t_name='叶平'
and sc.s_id=st.s_id
and sc.s_score=(select max(s_score) from score where c_id=c.c_id);
-- 不建议的一种方法
select s.s_id,st.s_name ,s_score from  score s,student st
where s.s_id=st.s_id
and s_score =(select max(s_score) from score  where c_id in(select ss.c_id from score ss,course c,teacher te where ss.c_id=c.c_id and c.t_id=te.t_id and te.t_name='叶平')  )
and s.c_id in(select ss.c_id from score ss,course c,teacher te where ss.c_id=c.c_id and c.t_id=te.t_id and te.t_name='叶平')

41、查询各个课程及相应的选修人数

select s.c_id, count(*) from score s where s.s_score is not null group by s.c_id

42、查询不同课程成绩相同的学生和学号、课程号、学生成绩

-- mysql 会认为要过滤掉s1.s_id,  s1.c_id,s1.s_score字段都重复的记录,所以一般distinct用来查询不重复记录的条数
select DISTINCT s1.s_id,  s1.c_id,s1.s_score from score s1, score s2   
where s1.s_id=s2.s_id
and s1.c_id <> s2.c_id
and s1.s_score=s2.s_score
-- 如果要查询不重复的记录,有时候可以用group by 
select s1.s_id,  s1.c_id,s1.s_score from score s1, score s2   
where s1.s_id=s2.s_id
and s1.c_id <> s2.c_id
and s1.s_score=s2.s_score
group by s1.c_id

43、查询每门课程成绩最好的前两名

[未完成2019年1月26日 17:45:02]

-- limit
select s.s_score from  score s order by s.s_score desc LIMIT 2 
select s.* from  score s  group by s.c_id -- 因为是按成绩分组 所以统计前两名就无法实现了
-- 思路:求成绩 in 前两名的数据

select s.s_id,t.s_name,s.s_score from score s ,student t
where s.s_score in (select s_score from  score   order by s_score desc LIMIT 2 )

44、统计每门课程的学生选修人数

(超过2人的课程才统计)。要求输出课程号和选修人数,查询结果按人数降序排序,若人数相同,按课程号升序排序

select s.c_id ,count(*) as rs 
from score s 
group by  s.c_id 
having rs >2
order by rs DESC,s.c_id  ASC

45、检索至少选修两门课程的学生学号

select s.s_id from  score s group by s.s_id having count(*)>2

46、查询全部学生选修的课程和课程号和课程名:

这个题目其实需求不明确的,下面的语句能求出录入过成绩的课程

select  c.c_id,c.c_name
from course c
where c.c_id in(select c_id from score group by c_id);

47、查询没学过”叶平”老师讲授的任一门课程的学生姓名

-- 下面这个语句没有实现需求,不过能求到三国叶平老师课程的学生 
select  s.s_id AS id ,st.s_name,s.c_id from score s,student st where  s.s_id=st.s_id and s.c_id  in(select c.c_id from course c,teacher t where c.c_id=t.t_id and t.t_name='叶平') ; --  因为成绩表里面没有学叶平老师的学生还会有其他的课程成绩,所以仍会有他的数据出现在结果里面
-- war 正确的
select s.s_id, s_name 
from student  s
where s.s_id not in (select s_id from course c,teacher t,score sc where c.t_id=t.t_id and sc.c_id=c.c_id 
and t.t_name='叶平');

48、查询两门以上不及格课程的同学的学号以及其平均成绩

-- 平均成绩,应该是所有课程的吧,那样思路就有了。先求出符合条件的学生,然后计算其平均成绩
select s_id ,avg(s_score) 
from score 
where s_id in 
(select s.s_id 
from score s 
where s.s_score <60  
group by s.s_id 
having count(s.s_score)>2) 
group by s_id;

-- 方法2
select s.s_id,avg(s.s_score) from score s group by s.s_id
having count(case when s.s_score<60 then s.c_id end)>2;

49、检索“01”课程分数小于60,按分数降序排列的同学学号

select s.s_id,s.s_score from score s where s.c_id='01' and s.s_score<60 order by s.s_score DESC

50、删除“02”同学的“01”课程的成绩:

delete from score s where s.s_id='02' and s.c_id='01'

本文链接:

https://ziyan1215.github.io/archive/1548494210/

# 最新文章