SQL经典五十道选刷

SQL经典五十道选刷(选了较有代表性的三十道,不代表最优解,仅提供思路)

--1.学生表

--- Student(S,Sname,Sage,Ssex)

--S 学生编号,Sname 学生姓名,Sage 出生年月,Ssex 学生性别

--2.课程表

-- Course(C,Cname,T)

--C --课程编号,Cname 课程名称,T 教师编号

--3.教师表

-- Teacher(T,Tname)

--T 教师编号,Tname 教师姓名

--4.成绩表

-- SC(S,C,score)

--S 学生编号,C 课程编号,score 分数

--创建测试数据

create table Student(S 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' , '孙风' , '1990-05-20' , '男');

insert into Student values('04' , '李云' , '1990-08-06' , '男');

insert into Student values('05' , '周梅' , '1991-12-01' , '女');

insert into Student values('06' , '吴兰' , '1992-03-01' , '女');

insert into Student values('07' , '郑竹' , '1989-07-01' , '女');

insert into Student values('08' , '王菊' , '1990-01-20' , '女');

create table Course(C varchar(10),Cname varchar(10),T varchar(10));

insert into Course values('01' , '语文' , '02');

insert into Course values('02' , '数学' , '01');

insert into Course values('03' , '英语' , '03');

create table Teacher(T varchar(10),Tname varchar(10));

insert into Teacher values('01' , '张三');

insert into Teacher values('02' , '李四');

insert into Teacher values('03' , '王五');

create table SC(S varchar(10),C 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);

-- 第一道,查询01课程成绩大于02课程成绩的学生信息及课程分数

SELECT

s.Sname,

s.Ssex,

s.Sage,

a.S,

a.C,

a.score score01,

b.score score02

FROM

( SELECT * FROM sc WHERE C = 01 ) a

INNER JOIN ( SELECT * FROM sc WHERE C = 02 ) b ON a.S = b.S

INNER JOIN student s ON a.S=s.S

WHERE

a.score > b.score;

-- 第二道,查询平均成绩大于等于60分的同学的学生编号和学生姓名和平均成绩

SELECT

s.Sname,

sc.S,

AVG( sc.score )

FROM

sc

INNER JOIN student s ON s.S = sc.S

GROUP BY

sc.S;

-- 第三道,查询所有同学的学生编号、学生姓名、选课总数、所有课程的总成绩

SELECT

s.S,

s.Sname,

count( sc.C ),

SUM( sc.score )

FROM

sc

INNER JOIN student s ON s.S = sc.S

GROUP BY

sc.S;

-- 第四道,查询"李"姓老师的数量

SELECT

COUNT( t.Tname )

FROM

teacher t

WHERE

t.Tname LIKE '李%';

-- 第五道,查询学过"张三"老师授课的同学的信息

SELECT

s.S,

s.Sname,

s.Sage,

s.Ssex

FROM

student s

INNER JOIN sc ON s.S = sc.S

WHERE

sc.C =(

SELECT

c.C

FROM

teacher t

INNER JOIN course c ON t.T = c.T

WHERE

t.Tname = '张三'

);

-- 第六道,查询没学过"张三"老师授课的同学的信息

SELECT

s.S,

s.Sname,

s.Sage,

s.Ssex

FROM

student s

WHERE

s.S NOT IN (

SELECT

s.S

FROM

student s

INNER JOIN sc ON s.S = sc.S

WHERE

sc.C =(

SELECT

c.C

FROM

teacher t

INNER JOIN course c ON t.T = c.T

WHERE

t.Tname = '张三'

));

-- 第七道,查询学过编号为"01"并且也学过编号为"02"的课程的同学的信息

SELECT

s.S,

s.Sname,

s.Sage,

s.Ssex

FROM

student s

INNER JOIN ( SELECT * FROM sc WHERE sc.C = '01' ) a ON s.S = a.S

INNER JOIN ( SELECT * FROM sc WHERE sc.C = '02' ) b ON s.S = b.S;

-- 第八道,查询学过编号为"01"但是没有学过编号为"02"的课程的同学的信息

SELECT

s.S,

s.Sname,

s.Sage,

s.Ssex

FROM

student s

INNER JOIN ( SELECT * FROM sc WHERE sc.C = '01' ) a ON a.S = s.S

WHERE

s.S NOT IN ( SELECT sc.S FROM sc WHERE sc.C = '02' );

-- 第九道,查询没有学全所有课程的同学的信息

SELECT

s.S,

s.Sname,

s.Sage,

s.Ssex,

COUNT( sc.C ) c_num

FROM

student s

INNER JOIN sc ON s.S = sc.S

GROUP BY

sc.S

HAVING

c_num <(

SELECT

COUNT( c.C )

FROM

course c)

-- 第十道,查询至少有一门课与学号为"01"的同学所学相同的同学的信息

SELECT DISTINCT

s.S,

s.Sname,

s.Sage,

s.Ssex

FROM

student s

INNER JOIN sc ON sc.S = s.S

WHERE

sc.C IN (

SELECT

sc.C

FROM

sc

WHERE

sc.S = '01');

-- 第十一道,查询和"01"号的同学学习的课程完全相同的其他同学的信息

SELECT

s.S,

s.Sname,

s.Sage,

s.Ssex,

GROUP_CONCAT( sc.C ORDER BY sc.C ) cs

FROM

student s

INNER JOIN sc ON sc.S = s.S

GROUP BY

sc.S

HAVING

cs =(

SELECT

GROUP_CONCAT( sc.C ORDER BY sc.C )

FROM

sc

WHERE

sc.S = '01'

);

-- 第十二道,查询没学过"张三"老师讲授的任一门课程的学生姓名

SELECT

s.S,

s.Sname

FROM

student s

INNER JOIN sc ON sc.S = s.S

GROUP BY

sc.S

HAVING

NOT FIND_IN_SET((

SELECT

GROUP_CONCAT( c.C )

FROM

course c

INNER JOIN teacher t ON t.T = c.T

WHERE

t.Tname = '张三'

),

GROUP_CONCAT( sc.C ));

-- 第十三道,查询两门及其以上不及格课程的同学的学号,姓名及其平均成绩

SELECT

s.Sname,

temp.S,

AVG( temp.score ) avg_score

FROM

( SELECT sc.S, sc.score FROM sc WHERE sc.score < 60 ) AS temp

INNER JOIN student s ON temp.S = s.S

GROUP BY

sc.S

HAVING

COUNT( temp.score )>=2;

-- 第十四道,检索"01"课程分数小于60,按分数降序排列的学生信息

SELECT

s.*,

sc.C,

sc.score

FROM

student s

INNER JOIN sc ON s.S = sc.S

WHERE

sc.S IN ( SELECT sc.S FROM sc WHERE sc.C = '01' AND sc.score < 60 )

ORDER BY

sc.score DESC

-- 第十五道,按平均成绩从高到低显示所有学生的所有课程的成绩以及平均成绩

SELECT

sc.S,

sc.C,

sc.score,

temp.avg_score

FROM

sc

INNER JOIN ( SELECT sc.S, AVG( sc.score ) avg_score FROM sc GROUP BY sc.S ) AS temp ON temp.S = sc.S

ORDER BY

avg_score DESC;

-- 第十六道,查询各科成绩最高分、最低分和平均分:以如下形式显示:--课程ID,课程name,最高分,最低分,平均分,及格率,中等率,优良率,优秀率--及格为>=60,中等为:70-80,优良为:80-90,优秀为:>=90

WITH t1 AS (SELECT sc.C,COUNT(sc.score) AS scores FROM sc WHERE sc.score >= 60 AND sc.score <= 70 GROUP BY sc.C),

t2 AS (SELECT sc.C,COUNT(sc.score) AS scores FROM sc WHERE sc.score>70 AND sc.score<=80 GROUP BY sc.C),

t3 AS (SELECT sc.C,COUNT(sc.score) AS scores FROM sc WHERE sc.score>80 AND sc.score<=90 GROUP BY sc.C),

t4 AS (SELECT sc.C,COUNT(sc.score) AS scores FROM sc WHERE sc.score>90 GROUP BY sc.C)

SELECT sc.C '课程ID',c.Cname '课程name',MAX(sc.score) '最高分',MIN(sc.score) '最低分',AVG(sc.score) '平均分',

ROUND(t1.scores/COUNT(sc.score),2) '及格率',

ROUND(t2.scores/COUNT(sc.score),2) '中等率',

ROUND(t3.scores/COUNT(sc.score),2) '优良率',

ROUND(t4.scores/COUNT(sc.score),2) '优秀率'

FROM sc

INNER JOIN course c ON sc.C=c.C

LEFT JOIN t1 ON sc.C=t1.C

LEFT JOIN t2 ON sc.C=t2.C

LEFT JOIN t3 ON sc.C=t3.C

LEFT JOIN t4 ON sc.C=t4.C

GROUP BY sc.C;

-- 第十七道,查询学生的总成绩并进行排名

SELECT

sc.S,

SUM( sc.score ) AS sum_score

FROM

sc

GROUP BY

sc.S

ORDER BY

sum_score DESC

-- 第十八道,查询不同老师所教不同课程平均分从高到低显示

SELECT

t.Tname,

sc.C,

AVG( sc.score ) AS avg_score

FROM

sc

INNER JOIN course c ON c.C = sc.C

INNER JOIN teacher t ON t.T = c.T

GROUP BY

sc.C

ORDER BY

avg_score DESC;

-- 第十九道,查询同名同性学生名单,并统计同名人数

SELECT s.Sname, COUNT( s.Sname ) AS rep_names

FROM student s

GROUP BY s.Sname

HAVING rep_names >= 2;

-- 第二十道,查询1990年出生的学生名单(注:Student表中Sage列的类型是datetime)

SELECT

s.S,

s.Sname

FROM

student s

WHERE

s.Sage BETWEEN '1990-01-01'

AND '1990-12-31';

-- 第二十一道,查询每门课程的平均成绩,结果按平均成绩降序排列,平均成绩相同时,按课程编号

SELECT

AVG( sc.score ) AS avg_score,

sc.C

FROM

sc

GROUP BY

sc.C

ORDER BY

avg_score,

sc.C;

-- 第二十二道,查询课程名称为"数学",且分数低于60的学生姓名和分数

WITH temp AS (

SELECT

c.C,

sc.S,

sc.score

FROM

sc

INNER JOIN course c ON c.C = sc.C

WHERE

c.Cname = '数学'

AND sc.score < 60

) SELECT

s.Sname,

sc.score

FROM

student s

INNER JOIN sc ON sc.S = s.S

INNER JOIN temp ON temp.S = s.S

WHERE

s.S = temp.S

AND sc.C = temp.C;

-- 第二十三道,查询不同课程成绩相同的学生的学生编号、课程编号、学生成绩

WITH temp AS ( SELECT sc.score FROM sc GROUP BY sc.score HAVING COUNT( sc.score )>= 2 ) SELECT

sc.S,

sc.C,

sc.score AS c_num

FROM

sc

INNER JOIN temp ON temp.score = sc.score

ORDER BY

sc.score;

-- 第二十四道,查询每门课成绩最好的前两名

WITH ranked_score AS (

SELECT

sc.S,

sc.C,

sc.score,

ROW_NUMBER() OVER ( PARTITION BY sc.C ORDER BY sc.score DESC ) AS rn

FROM

sc

) SELECT

S,

C,

score

FROM

ranked_score

WHERE

rn <= 2

ORDER BY

C,

score DESC;

-- 第二十五道,统计每门课程的学生选修人数(超过5人的课程才统计),要求输出课程号和选修人数,查询结果按人数降序排列,若人数相同,按课程号升序排列

SELECT sc.C, COUNT( sc.S ) AS s_num

FROM sc

GROUP BY sc.C

HAVING s_num > 5

ORDER BY s_num DESC,C;

-- 第二十六道,检索选修超过两门课程的学生学号

SELECT

sc.S

FROM

sc

GROUP BY

sc.S

HAVING

COUNT( sc.S )> 2;

-- 第二十七道,查询选修了全部课程的学生信息

SELECT

s.S,

s.Sname,

s.Ssex,

s.Sage

FROM

student s

INNER JOIN sc ON sc.S = s.S

GROUP BY

sc.S

HAVING

COUNT( sc.S )=(

SELECT

COUNT( c.C )

FROM

course c

);

-- 第二十八道,查询各学生的年龄

SELECT

s.S,

s.Sname,

TIMESTAMPDIFF( YEAR, s.Sage, CURRENT_DATE ) AS age

FROM

student s;

-- 第二十九道,查询本周过生日的学生

SELECT s.S, s.Sname, s.Sage

FROM student s

WHERE WEEK(s.Sage, 1) = WEEK(CURDATE(), 1)

AND DAYOFYEAR(s.Sage) >= DAYOFYEAR(CURDATE()) - WEEKDAY(CURDATE())

AND DAYOFYEAR(s.Sage) <= DAYOFYEAR(CURDATE()) + (6 - WEEKDAY(CURDATE()));

-- 第三十道,查询下个月过生日的学生

SELECT s.S,s.Sname,s.Sage

FROM student s

WHERE MONTH(s.Sage)=

CASE

WHEN MONTH(CURDATE()=12) THEN 1

ELSE MONTH(CURDATE())+1

END

AND YEAR(s.Sage)=

CASE

WHEN MONTH(CURDATE()=12) THEN YEAR(CURDATE())+1

ELSE YEAR(CURDATE())

END;

相关推荐
神仙别闹7 分钟前
基于java的改良版超级玛丽小游戏
java
你的微笑,乱了夏天20 分钟前
linux centos 7 安装 mongodb7
数据库·mongodb
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭31 分钟前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
工业甲酰苯胺31 分钟前
分布式系统架构:服务容错
数据库·架构
暮湫1 小时前
泛型(2)
java
超爱吃士力架1 小时前
邀请逻辑
java·linux·后端
南宫生1 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石1 小时前
12/21java基础
java
李小白661 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp1 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea