[資料庫]50道經典SQL練習題,使用MySQL5.7解答
資料表介紹
--1.學生表
Student(SId,Sname,Sage,Ssex)
--SId 學生編號,Sname 學生姓名,Sage 出生年月,Ssex 學生性別
--2.課程表
Course(CId,Cname,TId)
--CId 課程編號,Cname 課程名稱,TId 教師編號
--3.教師表
Teacher(TId,Tname)
--TId 教師編號,Tname 教師姓名
--4.成績表
SC(SId,CId,score)
--SId 學生編號,CId 課程編號,score 分數
練習題目
1.查詢" 01 “課程比” 02 "課程成績高的學生的資訊及課程分數
-- 此處可以先考慮分別查詢 01和02課程的學員id和分數
select SId,score from SC where CId = '01';
select SId,score from SC where CId = '02';
-- 對比結果可以清楚的知道,兩個表中有些SId不對應,不對應就沒有可比性
-- 因此可以對兩個結果做join,條件就是SId要相等,
-- 並且01的成績要比02大
select s1.SId,s1.score
from
(select SId,score from SC where CId = '01') s1
join
(select SId,score from SC where CId = '02') s2
on s1.SId = s2.SId
where s1.score > s2.score
-- 通過以上的sql得到了符合條件的學員id和分數,再到學員表中獲取學員資訊
select stu.SId,stu.Sname,s.score
from student as stu
right join (
select s1.SId,s1.score
from
(select SId,score from SC where CId = '01') s1
join
(select SId,score from SC where CId = '02') s2
on s1.SId = s2.SId
where s1.score > s2.score
) as s
on stu.SId = s.SId;
- 查詢同時存在" 01 “課程和” 02 "課程的情況
-- 本題和上一題內容相似,我們只需要把01和02的學員的SID作為連線條件就可以
select s1.*
from
(select SId,score from SC where CId = '01') s1
join
(select SId,score from SC where CId = '02') s2
on s1.SId = s2.SId
- 查詢存在" 01 “課程但可能不存在” 02 "課程的情況(不存在時顯示為 null )
select s1.SId,s2.score
from
(select SId,score from SC where CId = '01') s1
left join
(select SId,score from SC where CId = '02') s2
on s1.SId = s2.SId
- 查詢不存在" 01 “課程但存在” 02 "課程的情況
select * from SC
where SId not in(select SId from SC where CId = '01')
and CId = '02'
5.查詢平均成績大於等於 60 分的同學的學生編號和學生姓名和平均成績
-- 此題主要考核 分組後的條件過濾
select SC.SId,Sname,round(avg(score),2) as avg_score
from SC,Student
where SC.SId = Student.SId
group by SC.SId,Sname having avg_score >= 60;
6.查詢在 SC 表存在成績的學生資訊
-- 此題主要考核 資料去重 distinct
select distinct stu.* from Student stu join SC on SC.SId = stu.SId;
7.查詢所有同學的學生編號、學生姓名、選課總數、所有課程的總成績(沒成績的顯示為 null )
select stu.SId,stu.Sname,count(SC.CId) as total ,sum(SC.score) as sum_score
from Student as stu left join SC on stu.SId = SC.SId
group by stu.SId,stu.Sname;
8.查詢「李」姓老師的數量
select count(*) from teacher where Tname like '李%';
9.查詢學過「張三」老師授課的同學的資訊
select stu.*
from Student as stu
join SC on stu.SId = SC.SId
join course as C on SC.CId = C.CId
join Teacher as T on C.TId = T.TId
where T.Tname = '張三';
10.查詢沒有學全所有課程的同學的資訊
-- 排除法,找到所有學過全部課程的學生,
select * from Student where SId not in(
select SId from SC group by SId having count(CId) = (select count(*) from course)
)
11.查詢至少有一門課與學號為" 01 "的同學所學相同的同學的資訊
select distinct stu.*
from student as stu
left join sc on sc.SId = stu.SId
where sc.CId in (select CId from sc where SId = '01');
12.查詢和" 01 "號的同學學習的課程 完全相同的其他同學的資訊
-- 注意要對比的是課程ID號,在對比課程數
select s2.SId
from SC as s1 join SC as s2
on s1.CId = s2.CId and s1.SId = '01' and s2.SId != '01'
group by s2.SId
having count(s1.SId) = (select count(*) from SC where SId = '01');
select stu.*
from student as stu
left join sc on sc.SId = stu.SId
join ( select CId from sc where SId = '01') as t on t.CId = sc.CId
group by stu.SId having count(sc.SId) = 5;
13.查詢沒學過"張三"老師講授的任一門課程的學生姓名
select SId,Sname from Student where SId not in
(select SId from SC
where CId = (
select Course.Cid from Course
join Teacher on Teacher.TId = Course.TId
where Teacher.Tname = '張三'
))
14.查詢兩門及其以上不及格課程的同學的學號,姓名及其平均成績
select SC.SId,Student.Sname,round(avg(SC.score),2) as avg_sc
from SC join Student on Student.SId = SC.SId
where SC.score < 60 group by SC.SId,Student.Sname
having count(SC.CId) >=2;
15.檢索" 01 "課程分數小於 60,按分數降序排列的學生資訊
select SC.SId,Student.Sname,SC.score
from SC join Student on SC.SId = Student.SId
where SC.CId = '01' and SC.score < 60
order by SC.score desc;
16.按平均成績從高到低顯示所有學生的所有課程的成績以及平均成績
select SC.*,s2.avg_sc from SC
join (select SId, avg(score) as avg_sc from SC group by SId) as s2
on SC.SId = s2.SId
order by avg_sc desc, SC.SId;
--最佳解決方案 王宇鵬
select a.sname,b.score 語文,c.score 數學,d.score 英語,avg(e.score)
from student a
left join sc b on a.sid=b.sid and b.cid='01'
left join sc c on a.sid=c.sid and c.cid='02'
left join sc d on a.sid=d.sid and d.cid='03'
left join sc e on a.sid=e.sid
group by a.sname,語文,數學,英語
order by avg(e.score) desc;
17.查詢各科成績最高分、最低分和平均分:
以如下形式顯示:課程 ID,課程 name,最高分,最低分,平均分,及格率,中等率,優良率,優秀率 及格為>=60,中等為:70-80,優良為:80-90,優秀為:>=90
要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列
select SC.CId,C.Cname,
max(SC.score) as '最高分',
min(SC.score) as '最低分',
avg(SC.score) as '平均分',
count(SC.CId) as '選修人數',
SUM(CASE WHEN SC.score >= 60 THEN 1 ELSE 0 END) / count(SC.CId) as '及格率',
SUM(CASE WHEN SC.score >= 70 and SC.score < 80 THEN 1 ELSE 0 END) / count(SC.CId) as '中等率',
SUM(CASE WHEN SC.score >= 80 and SC.score < 90 THEN 1 ELSE 0 END) / count(SC.CId) as '優良率',
SUM(CASE WHEN SC.score >= 90 THEN 1 ELSE 0 END) / count(SC.CId) as '優秀率'
from SC,Course as C
where SC.CId = C.CId
group by SC.CId,C.Cname
order by '選修人數' desc,SC.CId;
18.按各科平均成績進行排序,並顯示排名, Score 重複時保留名次空缺
select s2.CId,s2.avg_sc,count(distinct s1.avg_sc) as Rank
from
(select avg(score) as avg_sc from SC group by CId) as s1
join
(select CId,avg(score) as avg_sc from SC group by CId) as s2
on s1.avg_sc >= s2.avg_sc
group by s2.CId order by Rank;
-- 解析過程
select s1.*,s2.*
from
(select CId,avg(score) as avg_sc from SC group by CId) as s1
join
(select CId,avg(score) as avg_sc from SC group by CId) as s2
on s1.avg_sc >= s2.avg_sc
group by s2.CId order by Rank;
-- 在這種情況下 去統計s1.平均分 還是去統計s2.平均分 的次數,資料中都有重複
-- 如果能把s1中的出現重複的平均分數去重,再去按照s1.平均分去統計次數就正常
+------+----------+------+----------+
| CId | avg_sc | CId | avg_sc |
+------+----------+------+----------+
| 01 | 64.50000 | 01 | 64.50000 |
| 02 | 79.33333 | 01 | 64.50000 |
| 03 | 70.00000 | 01 | 64.50000 |
| 04 | 79.30000 | 01 | 64.50000 |
--| 5 | 70.00000 | 01 | 64.50000 |
| 02 | 79.33333 | 02 | 79.33333 |
| 02 | 79.33333 | 03 | 70.00000 |
| 03 | 70.00000 | 03 | 70.00000 |
| 04 | 79.30000 | 03 | 70.00000 |
--| 5 | 70.00000 | 03 | 70.00000 |
| 02 | 79.33333 | 04 | 79.30000 |
| 04 | 79.30000 | 04 | 79.30000 |
| 02 | 79.33333 | 5 | 70.00000 |
| 03 | 70.00000 | 5 | 70.00000 |
| 04 | 79.30000 | 5 | 70.00000 |
--| 5 | 70.00000 | 5 | 70.00000 |
+------+----------+------+----------+
19.按各科平均成績進行排序,並顯示排名, Score 重複時不保留名次空缺
select b.CId,b.avg_sc,@i := @i+1 as Rank
from (select @i := 0) a,
(select CId,round(avg(Score),2) as avg_sc from SC group by CId order by avg_sc desc) b;
20.查詢學生的總成績,並進行排名,總分重複時保留名次空缺
select s2.SId,s2.avg_sc,count(distinct s1.avg_sc) as Rank
from
(select sum(score) as avg_sc from SC group by SId) as s1
join
(select SId,sum(score) as avg_sc from SC group by SId) as s2
on s1.avg_sc >= s2.avg_sc
group by s2.SId order by Rank;
21.查詢學生的總成績,並進行排名,總分重複時不保留名次空缺
select b.SId,b.avg_sc,@i := @i+1 as Rank
from (select @i := 0) a,
(select SId,sum(Score) as avg_sc from SC group by sId order by avg_sc desc) b;
22.統計各科成績各分數段人數:課程編號,課程名稱,[100-85],[85-70],[70-60],[60-0]及所佔百分比
select Course.CId,Course.Cname,
sum(CASE WHEN SC.score >= 85 and SC.score <= 100 THEN 1 ELSE 0 END) '[100-85]',
concat(round(sum(CASE WHEN SC.score >= 85 and SC.score <= 100 THEN 1 ELSE 0 END)/count(SC.SId),2)*100,'%') as '百分比',
sum(CASE WHEN SC.score >= 70 and SC.score < 85 THEN 1 ELSE 0 END) '[85-70]',
concat(round(sum(CASE WHEN SC.score >= 70 and SC.score < 85 THEN 1 ELSE 0 END)/count(SC.SId),2)*100,'%') as '百分比',
sum(CASE WHEN SC.score >= 60 and SC.score < 70 THEN 1 ELSE 0 END) '[70-60]',
concat(round(sum(CASE WHEN SC.score >= 60 and SC.score < 70 THEN 1 ELSE 0 END)/count(SC.SId),2)*100,'%') as '百分比',
sum(CASE WHEN SC.score >= 0 and SC.score < 60 THEN 1 ELSE 0 END) '[60-0]',
concat(round(sum(CASE WHEN SC.score >= 0 and SC.score < 60 THEN 1 ELSE 0 END)/count(SC.SId),2)*100,'%') as '百分比'
from SC,Course
where SC.CId = Course.CId
group by Course.CId,Course.Cname;
23.查詢各科成績前三名的記錄
(select CId,score from SC where CId = '01' order by score desc limit 3)
union all
(select CId,score from SC where CId = '02' order by score desc limit 3)
union all
(select CId,score from SC where CId = '03' order by score desc limit 3)
24.查詢每門課程被選修的學生數
select CId,count(SId) from SC group by CId;
25.查詢出只選修兩門課程的學生學號和姓名
select SC.SId,Student.Sname
from SC join Student on SC.SId = Student.SId
group by SC.SId,Student.Sname having count(SC.CId) = 2;
26.查詢男生、女生人數
select Ssex,count(*) from Student group by Ssex;
27.查詢名字中含有「風」字的學生資訊
select * from Student where Sname like '%風%';
28.查詢同名同性學生名單,並統計同名人數
select s1.Sname,count(s1.Sname)
from Student s1 join Student s2
on s1.Sname = s2.Sname and s1.Ssex = s2.Ssex and s1.SId != s2.SId
group by s1.Sname;
29.查詢 1990 年出生的學生名單
select * from Student where year(Sage) = 1990;
30.查詢每門課程的平均成績,結果按平均成績降序排列,平均成績相同時,按課程編號升序排列
select CId,avg(score) as avg_sc
from SC group by CId order by avg_sc desc,CId;
31.查詢平均成績大於等於 85 的所有學生的學號、姓名和平均成績
select SC.SId,Stu.Sname,round(avg(SC.score),2) as avg_sc
from SC join Student as Stu on SC.SId = Stu.SId
group by SC.SId,Stu.Sname having avg_sc >= 85;
32.查詢課程名稱為「數學」,且分數低於 60 的學生姓名和分數
select C.Cname,Stu.Sname,SC.score
from Course as C join SC on C.CId = SC.CId
join Student as Stu on SC.SId = Stu.SId
where C.Cname = '數學' and SC.score < 60;
33.查詢所有學生的課程及分數情況(存在學生沒成績,沒選課的情況)
select Student.Sname,Course.Cname,SC.score
from Student left join SC on Student.SId = SC.SId
left join Course on SC.CId = Course.CId
order by Student.Sname;
-- 張波
select a.SId,a.sname,b.score 語文,c.score 數學,d.score 英語
from student a
left join sc b on a.sid=b.sid and b.cid='01'
left join sc c on a.sid=c.sid and c.cid='02'
left join sc d on a.sid=d.sid and d.cid='03'
group by a.SId,a.sname,語文,數學,英語
order by a.Sid;
34.查詢任何一門課程成績在 70 分以上的姓名、課程名稱和分數
select Student.Sname,Course.Cname,SC.score
from Student,Course,SC
where Student.SId = SC.SId and SC.CId = Course.CId
and SC.score > 70;
35.查詢不及格的課程
select Student.Sname,Course.Cname,SC.score
from Student,Course,SC
where Student.SId = SC.SId and SC.CId = Course.CId
and SC.score < 60;
36.查詢課程編號為 01 且課程成績在 80 分以上的學生的學號和姓名
select SC.SId,Student.Sname
from SC join Student on SC.SId = Student.SId
where SC.Score > 80 and SC.CId = '01';
37.求每門課程的學生人數
select CId,count(SId) from SC group by CId;
38.成績不重複,查詢選修「張三」老師所授課程的學生中,成績最高的學生資訊及其成績
select Student.SId,Student.Sname,SC.score
from Student join SC on Student.SId = SC.SId
join Course on SC.CId = Course.CId
join Teacher on Teacher.TId = Course.TId
where Teacher.Tname = '張三';
order by SC.score desc limit 1;
39.成績有重複的情況下,查詢選修「張三」老師所授課程的學生中,成績最高的學生資訊及其成績
-- 查詢張三老師授課的學生中最高分數,查詢所有等於最高分的
-- -- 先查詢最高分數
-- select max(SC.score)
-- from SC join Course on SC.CId = Course.CId
-- join Teacher on Teacher.TId = Course.TId
-- where Teacher.Tname = '張三'
-- 追加 分數條件
select Student.SId,Student.Sname,SC.score
from Student join SC on Student.SId = SC.SId
join Course on SC.CId = Course.CId
join Teacher on Teacher.TId = Course.TId
where Teacher.Tname = '張三'
and SC.score = (select max(SC.score)
from SC join Course on SC.CId = Course.CId
join Teacher on Teacher.TId = Course.TId
where Teacher.Tname = '張三');
-- 王宇鵬
select a.sname,b.score
from student a join sc b on a.sid=b.sid
and b.cid in (select cid from course where tid in (select tid from teacher where tname='張三'))
join (select cid,max(score) m from sc group by cid) c on b.cid=c.cid and b.score=c.m;
-- 張波
select stu.*,
max(SC.score) as 成績
from Student as stu
join SC on stu.SId = SC.SId
join course as C on SC.CId = C.CId
join Teacher as T on C.TId = T.TId
where T.Tname = '張三';
40.查詢不同課程成績相同的學生的學生編號、課程編號、學生成績
select s1.CId,s1.SId,s1.Score
from SC s1 join SC s2
on s1.CId != s2.CId and s1.score = s2.score and s1.SId = s2.SId
order by s1.Score;
select distinct s1.SId,s1.CId,s1.Score
from SC s1 join SC s2
on s1.CId != s2.CId and s1.score = s2.score
group by s1.SId,s1.CId,s1.Score
SELECT DISTINCT s1.sid,s1.cid,s1.score
FROM sc s1,sc s2 WHERE s1.cid != s2.cid AND s1.score = s2.score
41.查詢每門課程成績最好的前兩名
(select CId,score from SC where CId = '01' order by score desc limit 2)
union all
(select CId,score from SC where CId = '02' order by score desc limit 2)
union all
(select CId,score from SC where CId = '03' order by score desc limit 2)
42.統計每門課程的學生選修人數(超過 5 人的課程才統計)。
select CId,count(SId) from SC group by CId having count(SId) > 5;
43.檢索至少選修兩門課程的學生學號
select SId,count(CId) as num from SC group by SId having num >=2;
44.查詢選修了全部課程的學生資訊
select SId from SC group by SId
having count(CId) = (select count(*) from Course);
45.查詢各學生的年齡,只按年份來算
select Stu.SId,Stu.Sname,(year(now()) - year(Stu.Sage)) as '年齡'
from Student as stu;
46.按照出生日期來算,當前月日 < 出生年月的月日則,年齡減一
TIMESTAMPDIFF() 從日期時間表示式中減去間隔
https://dev.mysql.com/doc/refman/5.7/en/date-and-time-functions.html
select student.SId,student.Sname,
TIMESTAMPDIFF(YEAR,student.Sage,CURDATE()) from student
47.查詢本週過生日的學生
返回日期從範圍內的數字日曆星期1到53
select *from student
where WEEKOFYEAR(student.Sage)=WEEKOFYEAR(CURDATE());
48.查詢下週過生日的學生
select *
from student
where WEEKOFYEAR(student.Sage)=WEEKOFYEAR(CURDATE())+1;
49.查詢本月過生日的學生
select *
from student
where MONTH(student.Sage)=MONTH(CURDATE());
50.查詢下月過生日的學生
select *
from student
where MONTH(student.Sage)=MONTH(CURDATE())+1;
資料Data
--學生表 Student
create table Student(SId 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-12-20' , '男');
insert into Student values('04' , '李雲' , '1990-12-06' , '男');
insert into Student values('05' , '周梅' , '1991-12-01' , '女');
insert into Student values('06' , '吳蘭' , '1992-01-01' , '女');
insert into Student values('07' , '鄭竹' , '1989-01-01' , '女');
insert into Student values('09' , '張三' , '2017-12-20' , '女');
insert into Student values('10' , '李四' , '2017-12-25' , '女');
insert into Student values('11' , '李四' , '2012-06-06' , '女');
insert into Student values('12' , '趙六' , '2013-06-13' , '女');
insert into Student values('13' , '孫七' , '2014-06-01' , '女');
-- 科目表 Course
create table Course(CId varchar(10),Cname nvarchar(10),TId varchar(10));
insert into Course values('01' , '語文' , '02');
insert into Course values('02' , '數學' , '01');
insert into Course values('03' , '英語' , '03');
-- 教師表 Teacher
create table Teacher(TId varchar(10),Tname varchar(10));
insert into Teacher values('01' , '張三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');
-- 成績表 SC
create table SC(SId varchar(10),CId 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);
相關文章
- SQL經典練習題48道之一(1-10)SQL
- SQL經典練習題48道之二(11-19)SQL
- SQL經典練習題48道之三(20-25)SQL
- SQL經典練習題48道之四(26-30)SQL
- SQL經典練習題48道之五(31-35)SQL
- SQL經典練習題48道之六(36-40)SQL
- SQL經典練習題48道之七(41-48)SQL
- 【MySQL】經典資料庫SQL語句編寫練習題——SQL語句掃盲MySql資料庫
- 資料庫大型應用——筆記2 50道mysql練習題資料庫筆記MySql
- 50道經典的JAVA程式設計題(目錄)Java程式設計
- 50道Java基礎程式設計練習題Java程式設計
- 一道sql面試題的解答SQL面試題
- 資料庫精通練習題答案資料庫
- 網路資料庫練習題資料庫
- 5道較難的資料庫查詢習題(Intermediate SQL)資料庫SQL
- 小菜菜mysql練習50題解析——資料準備MySql
- 20道JavaScript經典面試題JavaScript面試題
- 多表查詢經典練習
- 30 個 Openstack 經典面試問題和解答面試
- 資料庫練習資料庫
- 記一道經典前端題前端
- SQL經典五十道題SQL
- 經典SQL面試題1SQL面試題
- 經典SQL面試題2SQL面試題
- SQL 練習題SQL
- SQL練習題SQL
- [學習資料]稀缺的音視訊,50道音視訊經典面試題,國內國外大佬教學視訊,N個經典開源專案,建議收藏面試題
- 字串函式庫的經典使用學習字串函式
- SQL經典面試題及答案SQL面試題
- oracle sql練習題OracleSQL
- MongoDB資料庫經典面試問答MongoDB資料庫面試
- 大資料經典學習路線大資料
- 資料庫 (相關練習)資料庫
- 資料庫語句練習資料庫
- 【整理】8道Python經典面試題合集!Python面試題
- 深度學習從入門到進階的12個經典問題及解答深度學習
- SQL language裡面的經典問題SQL
- 揹包問題的一道經典問題