sql练习题(3)

-- 16、检索"01"课程分数小于60,按分数降序排列的学生信息

SELECT s.*, s1.`s_score` FROM student s
LEFT JOIN score s1 ON s.`s_id` = s1.`s_id`WHERE s1.`s_score` < 60 AND s1.`c_id` = '01' ORDER BY s1.`s_score` DESC

-- 17、按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

SELECT a.s_id,
(SELECT s_score FROM score WHERE s_id=a.s_id AND c_id='01') AS 语文,
(SELECT s_score FROM score WHERE s_id=a.s_id AND c_id='02') AS 数学,
(SELECT s_score FROM score WHERE s_id=a.s_id AND c_id='03') AS 英语,
ROUND(AVG(s_score),2) AS 平均分 
FROM score a  
GROUP BY a.s_id 
ORDER BY 平均分 DESC;

-- mark 为什么max(函数)
-- 因为使用group by 之后只会保留一行数据,因此case when 要借助sum\max\min函数,保留其他列的值(即聚合函数sum配合 case when实现多表left join的行转列)
SELECT a.s_id,
MAX(CASE a.c_id WHEN '01' THEN a.s_score END)  语文, 
MIN(CASE a.c_id WHEN '02' THEN a.s_score END)  数学, 
SUM(CASE a.c_id WHEN '03' THEN a.s_score END)  英语, 
AVG(a.s_score), 
b.s_name
 FROM Score a JOIN Student b ON a.s_id = b.s_id GROUP BY a.s_id ORDER BY 5 DESC
 
 -- 18.查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率
-- 及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90
SELECT a.c_id,b.c_name,MAX(s_score),MIN(s_score),ROUND(AVG(s_score),2),
ROUND(100*(SUM(CASE WHEN a.s_score>=60 THEN 1 ELSE 0 END)/SUM(CASE WHEN a.s_score THEN 1 ELSE 0 END)),2) AS 及格率,
ROUND(100*(SUM(CASE WHEN a.s_score>=70 AND a.s_score<=80 THEN 1 ELSE 0 END)/SUM(CASE WHEN a.s_score THEN 1 ELSE 0 END)),2) AS 中等率,
ROUND(100*(SUM(CASE WHEN a.s_score>=80 AND a.s_score<=90 THEN 1 ELSE 0 END)/SUM(CASE WHEN a.s_score THEN 1 ELSE 0 END)),2) AS 优良率,
ROUND(100*(SUM(CASE WHEN a.s_score>=90 THEN 1 ELSE 0 END)/SUM(CASE WHEN a.s_score THEN 1 ELSE 0 END)),2) AS 优秀率
FROM score a
LEFT JOIN course b ON a.c_id = b.c_id 
GROUP BY a.c_id,b.c_name
	

-- 19、按各科成绩进行排序,并显示排名
-- mysql没有rank函数
SELECT a.s_id,a.c_id,
 @i:=@i +1 AS i保留排名,
 @k:=(CASE WHEN @score=a.s_score THEN @k ELSE @i END) AS rank不保留排名,
 @score:=a.s_score AS score
 FROM (
 SELECT s_id,c_id,s_score FROM score GROUP BY s_id,c_id,s_score ORDER BY s_score DESC
)a,(SELECT @k:=0,@i:=0,@score:=0)s

-- 20、查询学生的总成绩并进行排名
SELECT s.s_id,s.s_name,SUM(s1.s_score) 总成绩 FROM student s, score s1
WHERE s.s_id = s1.s_id
GROUP BY s.s_id, s.s_name
ORDER BY 3 DESC

SELECT a.s_id,
	@i:=@i+1 AS i,
	@k:=(CASE WHEN @score=a.sum_score THEN @k ELSE @i END) AS rank0,
	@score:=a.sum_score AS score
FROM (
 SELECT s_id,SUM(s_score) AS sum_score FROM score GROUP BY s_id ORDER BY sum_score DESC)a,
 SELECT @k:=0,@i:=0,@score:=0
 )s
-- 21、查询不同老师所教不同课程平均分从高到低显示 
SELECT  t.`t_name`,c.`c_name`,ROUND(AVG(s.`s_score`),2) 平均成绩 FROM teacher t 
LEFT JOIN course c ON t.`t_id` = c.`t_id` 
LEFT JOIN score s ON c.`c_id` = s.`c_id`
GROUP BY t.`t_name`
ORDER BY 平均成绩 DESC

-- 22、查询所有课程的成绩第2名到第3名的学生信息及该课程成绩
	SELECT d.*,c.排名,c.s_score,c.c_id FROM (
                SELECT a.s_id,a.s_score,a.c_id,@i:=@i+1 AS 排名 FROM score a,(SELECT @i:=0)s WHERE a.c_id='01'  
								ORDER BY a.s_score DESC  
            )c
            LEFT JOIN student d ON c.s_id=d.s_id
            WHERE 排名 BETWEEN 2 AND 3
            UNION
            SELECT d.*,c.排名,c.s_score,c.c_id FROM (
                SELECT a.s_id,a.s_score,a.c_id,@j:=@j+1 AS 排名 FROM score a,(SELECT @j:=0)s WHERE a.c_id='02'  
								ORDER BY a.s_score DESC
            )c
            LEFT JOIN student d ON c.s_id=d.s_id
            WHERE 排名 BETWEEN 2 AND 3
            UNION
            SELECT d.*,c.排名,c.s_score,c.c_id FROM (
                SELECT a.s_id,a.s_score,a.c_id,@k:=@k+1 AS 排名 FROM score a,(SELECT @k:=0)s WHERE a.c_id='03' 
								ORDER BY a.s_score DESC
            )c
            LEFT JOIN student d ON c.s_id=d.s_id
            WHERE 排名 BETWEEN 2 AND 3;
-- 23、统计各科成绩各分数段人数:课程编号,课程名称,[100-85],[85-70],[70-60],[0-60]及所占百分比

SELECT DISTINCT f.c_name,a.c_id,b.`85-100`,b.百分比,c.`70-85`,c.百分比,d.`60-70`,d.百分比,e.`0-60`,e.百分比 
FROM score a
LEFT JOIN (SELECT c_id,SUM(CASE WHEN s_score >85 AND s_score <=100 THEN 1 ELSE 0 END) AS `85-100`,
ROUND(100*(SUM(CASE WHEN s_score >85 AND s_score <=100 THEN 1 ELSE 0 END)/COUNT(*)),2) AS 百分比
FROM score GROUP BY c_id)b ON a.c_id=b.c_id
LEFT JOIN (SELECT c_id,SUM(CASE WHEN s_score >70 AND s_score <=85 THEN 1 ELSE 0 END) AS `70-85`,
ROUND(100*(SUM(CASE WHEN s_score >70 AND s_score <=85 THEN 1 ELSE 0 END)/COUNT(*)),2) AS 百分比
FROM score GROUP BY c_id)c ON a.c_id=c.c_id
LEFT JOIN (SELECT c_id,SUM(CASE WHEN s_score >60 AND s_score <=70 THEN 1 ELSE 0 END) AS `60-70`,
ROUND(100*(SUM(CASE WHEN s_score >60 AND s_score <=70 THEN 1 ELSE 0 END)/COUNT(*)),2) AS 百分比
FROM score GROUP BY c_id)d ON a.c_id=d.c_id
LEFT JOIN (SELECT c_id,SUM(CASE WHEN s_score >=0 AND s_score <=60 THEN 1 ELSE 0 END) AS `0-60`,
ROUND(100*(SUM(CASE WHEN s_score >=0 AND s_score <=60 THEN 1 ELSE 0 END)/COUNT(*)),2) AS 百分比
FROM score GROUP BY c_id)e ON a.c_id=e.c_id
LEFT JOIN course f ON a.c_id = f.c_id

-- 24、查询学生平均成绩及其名次

-- 保留空缺排名,是指当平均成绩相同时,出现并列名次
SELECT a.s_id,
@i:=@i+1 AS '不保留空缺排名',
@k:=(CASE WHEN @avg_score = a.avg_s THEN @k ELSE @i END) AS '保留空缺排名',
@avg_score:=avg_s AS '平均分'
FROM (SELECT s_id,ROUND(AVG(s_score),2) AS avg_s FROM score
GROUP BY s_id 
ORDER BY avg_s DESC)a,
(SELECT @avg_score:=0,@i:=0,@k:=0)b;

  

猜你喜欢

转载自www.cnblogs.com/Aug-20/p/12046660.html