title: SQL练习
time: 2019年8月16日16:09:54
tags: SQL
SQL 练习
- 查询至少有一门课与学号为“01”的学生所学课程相同的学生的学号和姓名(重点)
SELECT
s_id,
s_name
FROM
student
WHERE
s_id IN (
SELECT DISTINCT
s_id
FROM
score
WHERE
c_id IN ( SELECT c_id FROM score WHERE s_id = '01' )
AND s_id != '01'
)
- 查询和“01”号同学所学课程完全相同的其他同学的学号(重点)
SELECT
s_id
FROM
score
GROUP BY
s_id
HAVING
count( c_id ) = ( SELECT count( c_id ) FROM score WHERE s_id = '01' )
AND s_id != '01'
- 查询没学过"张三"老师讲授的任一门课程的学生姓名(重点,能做出来)
-- 查询没学过"张三"老师讲授的任一门课程的学生姓名 和47题一样(重点,能做出来)
SELECT
s_name
FROM
student
WHERE
s_id NOT IN (
SELECT
s_id
FROM
score AS s
INNER JOIN course AS c ON c.c_id = s.c_id
INNER JOIN teacher AS t ON t.t_id = c.t_id
WHERE
t_name = '张三'
)
- 查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩(重点)
SELECT
s.s_id,
s.s_name,
a.avg
FROM
student AS s
INNER JOIN ( SELECT s_id, avg( s_score ) AS avg FROM score WHERE s_score < 60 GROUP BY s_id HAVING count( c_id ) >= 2 ) AS a ON s.s_id = a.s_id
- 检索"01"课程分数小于60,按分数降序排列的学生信息
SELECT
s.s_id,
s.s_name,
s.s_birth,
s.s_sex,
a.s_score
FROM
student AS s
INNER JOIN ( SELECT s_id, s_score FROM score WHERE s_score < 60 AND c_id = '01' ORDER BY s_score DESC ) AS a ON s.s_id = a.s_id
- 检索"01"课程分数小于60,按分数升序排列的学生信息
SELECT
s.s_id,
s.s_name,
s.s_birth,
s.s_sex,
a.s_score
FROM
student AS s
INNER JOIN ( SELECT s_id, s_score FROM score WHERE s_score < 60 AND c_id = '01' ORDER BY s_score ASC ) AS a ON s.s_id = a.s_id
- 按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩(重重点)
-- SQL中的别名 一般不用加双引号和单引号 直接 把别名输入在后边即可,或者加个as
-- 为01,字符值时,也可不用加,如:where name = 李赏 如: where id = 01
SELECT
s_id 学号,
max( CASE WHEN c_id = 02 THEN s_score ELSE NULL END )语文,
min( CASE WHEN c_id = 01 THEN s_score ELSE NULL END ) 数学,
max( CASE WHEN c_id = 03 THEN s_score ELSE NULL END )英语,
avg( s_score ) 平均成绩
FROM
score
GROUP BY
s_id
ORDER BY
平均成绩 DESC
-
查询各科成绩最高分、最低分和平均分:以如下形式显示:课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90 (超级重点)
select s.c_id , c.c_name , MAX(s.s_score) 最高分 , MIN(s.s_score) 最低分 , AVG(s.s_score) 平均分 , SUM(case when s.s_score >= 60 then 1 ELSE 0 END) / COUNT(s.s_id) 及格率 , SUM(case when s.s_score >= 70 and s.s_score <80 then 1 ELSE 0 END ) / COUNT(s.s_id) 中等率 , SUM(case when s.s_score >= 80 and s.s_score <90 then 1 ELSE 0 END ) / COUNT(s.s_id) 优良率 , SUM(case when s.s_score >= 90 then 1 ELSE 0 END ) / COUNT(s.s_id) 优秀率 FROM score as s inner JOIN course as c on s.c_id = c.c_id GROUP BY c_id
-
按各科成绩进行排序,并显示排名(重点row_number)
-- rank() over (partition by ..(按什么分组)(每一组都是从1开始的) order by ..(按什么排序)) --> 跳跃式 排序,如:第二名第三名成绩一样,他们排名都是2, 第三名下个直接是4 -- dense_rank() over (partition by ..(按什么分组) order by ..(按什么排序)) --> 连续 排序,如:第二名第三名成绩一样,他们排名都是2, 第三名下个直接是3 -- row_number() over (partition by ..(按什么分组) order by ..(按什么排序)) --> 连续 排序,如:第二名第三名成绩一样,第一个排名是2另一个排名3,, 第三名下个直接是4 SELECT s_id, c_id, s_score, ROW_number () over ( PARTITION BY c_id ORDER BY s_score DESC ) AS rank FROM score
-
查询学生的总成绩并进行排名(不重点)
SELECT s_id, SUM( s_score ) AS 总成绩 FROM score GROUP BY s_id ORDER BY 总成绩 DESC
-
查询不同老师所教不同课程平均分从高到低显示(不重点)
SELECT c_id, AVG( s_score ) FROM score GROUP BY c_id DESC
-
查询所有课程的成绩第2名到第3名的学生信息及该课程成绩(重要 )
SELECT s.s_id, st.s_name, st.s_sex, st.s_birth, s.c_id, s.s_score, row_number over ( PARTITION BY c_id ORDER BY s_score DESC ) rank FROM score AS s INNER JOIN student AS st ON st.s_id = s.s_id WHERE s.rank IN ( 2, 3 )
-
使用分段[100-85],[85-70],[70-60],[<60]来统计各科成绩,分别统计各分数段人数:课程ID和课程名称
SELECT s.c_id, c.c_name, sum( CASE WHEN s.s_score <= 100 AND s.s_score > 85 THEN 1 ELSE 0 END ) '[100 , 85)', count( CASE WHEN s.s_score <= 85 AND s.s_score > 70 THEN 1 ELSE NULL END ) '[85 , 70)', sum( CASE WHEN s.s_score <= 70 AND s.s_score > 60 THEN 1 ELSE 0 END ) '[70 , 60)', sum( CASE WHEN s.s_score < 60 THEN 1 ELSE 0 END ) '<60' FROM score AS s INNER JOIN course AS c ON s.c_id = c.c_id GROUP BY s.c_id
-
查询学生平均成绩及其名次(重点)
SELECT s_id, AVG( s_score ) AS avg, row_number () over ( ORDER BY avg DESC ) FROM score GROUP BY s_id
-
查询各科成绩前三名的记录(不考虑成绩并列情况)(重点 )
SELECT c_id, row_number () over ( PARTITION BY c_id ORDER BY s_score DESC ) AS rank FROM score WHERE rank IN ( 1, 2, 3 )
-
查询每门课程被选修的学生数(不重点)
SELECT c_id, count( s_id ) FROM score GROUP BY c_id
-
查询出只有两门课程的全部学生的学号和姓名(不重点)
-- GROUP BY 不能加where 筛选 -- 只能有having进行筛选 -- GROUP BY .. having.. 必须在表连接之后进行操作 SELECT s.s_id, st.s_name, count( s.s_id ) AS cid FROM score AS s INNER JOIN student AS st ON st.s_id = s.s_id GROUP BY s.s_id HAVING cid = 2
hving进行筛选
-- GROUP BY .. having.. 必须在表连接之后进行操作
SELECT
s.s_id,
st.s_name,
count( s.s_id ) AS cid
FROM
score AS s
INNER JOIN student AS st ON st.s_id = s.s_id
GROUP BY
s.s_id
HAVING
cid = 2