【建表并導入數據】
--建表
--學生表
CREATE TABLE `Student`(
`s_id` VARCHAR(20),
`s_name` VARCHAR(20) NOT NULL DEFAULT '',
`s_birth` VARCHAR(20) NOT NULL DEFAULT '',
`s_sex` VARCHAR(10) NOT NULL DEFAULT '',
PRIMARY KEY(`s_id`)
);
--課程表
CREATE TABLE `Course`(
`c_id` VARCHAR(20),
`c_name` VARCHAR(20) NOT NULL DEFAULT '',
`t_id` VARCHAR(20) NOT NULL,
PRIMARY KEY(`c_id`)
);
--教師表
CREATE TABLE `Teacher`(
`t_id` VARCHAR(20),
`t_name` VARCHAR(20) NOT NULL DEFAULT '',
PRIMARY KEY(`t_id`)
);
--成績表
CREATE TABLE `Score`(
`s_id` VARCHAR(20),
`c_id` VARCHAR(20),
`s_score` INT(3),
PRIMARY KEY(`s_id`,`c_id`)
);
--插入學生表測試數據
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' , '女');
--課程表測試數據
insert into Course values('01' , '語文' , '02');
insert into Course values('02' , '數學' , '01');
insert into Course values('03' , '英語' , '03');
--教師表測試數據
insert into Teacher values('01' , '張三');
insert into Teacher values('02' , '李四');
insert into Teacher values('03' , '王五');
--成績表測試數據
insert into Score values('01' , '01' , 80);
insert into Score values('01' , '02' , 90);
insert into Score values('01' , '03' , 99);
insert into Score values('02' , '01' , 70);
insert into Score values('02' , '02' , 60);
insert into Score values('02' , '03' , 80);
insert into Score values('03' , '01' , 80);
insert into Score values('03' , '02' , 80);
insert into Score values('03' , '03' , 80);
insert into Score values('04' , '01' , 50);
insert into Score values('04' , '02' , 30);
insert into Score values('04' , '03' , 20);
insert into Score values('05' , '01' , 76);
insert into Score values('05' , '02' , 87);
insert into Score values('06' , '01' , 31);
insert into Score values('06' , '03' , 34);
insert into Score values('07' , '02' , 89);
insert into Score values('07' , '03' , 98);
筆試題
*1、查詢課程編號為“01”的課程比“02”的課程成績高的所有學生的學號。
思路:使用自聯結把01課程當作表a查出成績,02課程當作表b查出成績,表a和表b的學號相等,保證查詢的是同一個人,然后進行成績的比較
-- 寫法一:
select a.s_id
from Score a join Score b on a.s_id = b.s_id and a.s_score >b.s_score
where a.c_id = '01' and b.c_id= '02';
-- 寫法二:
select a.s_id
from (select * from Score where c_id = '01') as a
join (select * from Score where c_id='02') as b
on a.s_id = b.s_id
where a.s_score > b.s_score;
2、查詢平均成績大于60分的學生的學號和平均成績
思路: 按學號進行分組,計算出每個學生各科的成績,然后求出平均成績
select s_id, avg(s_score)
from Score
group by s_id
having avg(s_score)>60;
3、查詢所有學生的學號、姓名、選課數、總成績
思路:姓名屬于Student表,其它屬于Score表,考慮內聯結
select Score.s_id, Student.s_name,count(c_id),sum(s_score)
from Score join Student on Score.s_id = Student.s_id
group by s_id,s_name;
4、查詢姓“張”的老師的個數
思路:like的用法
select count(t_id)
from Teacher
where t_name like '張%';
*5.查詢沒學過“張三”老師課的學生的學號、姓名(重點)
思路: 查出張三老師教過什么課,并把張三老師教過的課當作一張表,而查詢的學生不在這張表中
select s_id, s_name
from Student
where s_id not in
(select s_id from Score join Course on Score.c_id = Course.c_id
join Teacher on Course.t_id = Teacher.t_id
where t_name = '張三');
6、查詢學過“張三”老師所教的所有課的同學的學號、姓名
select s_id, s_name
from Student
where s_id in
(select s_id from Score join Course on Score.c_id = Course.c_id
join Teacher on Course.t_id = Teacher.t_id
where t_name = '張三');
*7、查詢學過編號為“01”的課程并且也學過編號為“02”的課程的學生的學號、姓名
自聯結。把學過表01課程的學生當作表a,學過02課程的學生當作表b,分別從這兩張表中取出同一個學生學習過的課程
select s_id, s_name
from Student
where s_id in
(select a.s_id from
(select s_id from Score where c_id = '01') as a
join (select s_id from Score where c_id ='02') as b
on a.s_id= b.s_id);
8、查詢課程編號為“02”的總成績
select sum(s_score)
from Score
where c_id = '02';
9、查詢所有課程成績小于60分的學生的學號、姓名
思路:按學生進行分組,查詢每個學生所有課程的成績
select Student.s_id, Student.s_name
from Student join Score on Student.s_id= Score.s_id
where Score.s_score <60
group by s_id, s_name;
10、查詢沒有學全所有課的學生的學號、姓名
思路:按學生進行分組,查出每個學生學習課程的數量,再跟課程總數相比
select Student.s_id, Student.s_name
from Student join Score on Score.s_id = Student.s_id
group by s_id, s_name
having count(Score.c_id) < (select count(c_id) from Course);
*11、查詢至少有一門課與學號為“01”的學生所學課程相同的學生的學號和姓名
思路:1. 查出01學生學了什么課程;2. 查詢出的結果要排除01學生
select distinct Student.s_id, Student.s_name
from Student join Score on Student.s_id= Score.s_id
where c_id in
(select c_id from Score where s_id = '01')
and Student.s_id<>'01';
*12、查詢和“01”號同學所學課程完全相同的其他同學的學號
思路:課程完全相同表示學習的科目相同,學習的課程數也相同。
select s_id
from Score
where c_id in
(select c_id from Score where s_id='01')
and s_id <> '01'
group by s_id
having count(c_id)=(select count(c_id) from Score where s_id='01');
*13、把“SCORE”表中“張三”老師教的課的成績都更改為此課程的平均成績
思路:表有主鍵的情況下,不可以使用insert,應該使用update。使用update需要注意:set不能接復雜條件。把Score當成一張表,把計算出張三老師教的課的平均成績當作另外一張表
update Score as a
join
(select avg(s_score) as t, Score.c_id from Score join Course on Score.c_id= Course.c_id
join Teacher on Teacher.t_id= Course.t_id
where t_name ='張三'
group by c_id) as b
on a.c_id= b.c_id
set a.s_score= b.t;
14、查詢和“02”號的同學學習的課程完全相同的其他同學學號和姓名(同12題)
15、刪除學習“張三”老師課的SC表記錄
delete from Score
where c_id in
(select c_id from Course join Teacher on Course.t_id=Teacher.t_id
where t_name ='張三');
*17、按平均成績從高到低顯示所有學生的“數據庫”(c_id='04')、“企業管理”(c_id='01')、“英語”(c_id='06')三門的課程成績,按如下形式顯示:學生ID,數據庫,企業管理,英語,有效課程數,有效平均分
思路:按學生進行分組,顯示學生各科成績。由于科目唯一時,會返回多個值(例如查詢數據庫的成績,會返回多個學生對應數據庫的成績),此時應注意使用別名進行區別嵌套
select s_id as '學生ID',
(select s_score from Score where Score.s_id= sc.s_id and c_id = '04') as '數據庫',
(select s_score from Score where Score.s_id= sc.s_id and c_id = '01') as '企業管理',
(select s_score from Score where Score.s_id= sc.s_id and c_id = '06') as '英語',
count(c_id) as 有效課程數,
avg(s_score) as 有效平均分
from Score as sc
group by s_id
order by avg(s_score) DESC;
18、查詢各科成績最高和最低的分: 以如下的形式顯示:課程ID,最高分,最低分
思路:按科目進行分組
select c_id as 課程ID,
max(s_score) as 最高分,
min(s_score) as 最低分
from Score
group by c_id;
*19、按各科平均成績從低到高和及格率的百分數從高到低排列,以如下形式顯示:課程號,課程名,平均成績,及格百分數
思路:及格百分數=及格率=及格人數/總人數。
select Course.c_id as '課程號',
Course.c_name as '課程名',
avg(Score.s_score) as '平均成績',
concat(d.c/a.b*100,'%') as '及格百分數'
from (select c_id,count(distinct s_id) as b from Score group by c_id) as a
join (select c_id,count(distinct s_id) as c from Score where s_score >=60 group by c_id) as d
on a.c_id=d.c_id
join Course on a.c_id=Course.c_id
join Score on Course.c_id=Score.c_id
group by Course.c_id,Course.c_name
order by 平均成績, 及格百分數 DESC;
20、查詢如下課程平均成績和及格率的百分數(用1行顯示),其中企業管理為001,馬克思為002,UML為003,數據庫為004
略
21、查詢不同老師所教不同課程平均分從高到低顯示
思路:按老師、科目進行分組,不同表之間要內聯結
select Teacher.t_id,Teacher.t_name,Course.c_name,avg(Score.s_score)
from Teacher join Course on Teacher.t_id=Course.t_id
join Score on Course.c_id=Score.c_id
group by t_id,t_name,c_name
order by avg(Score.s_score) DESC;
*23、使用分段[100-85],[85-70],[70-60],[<60]來統計各科成績,分別統計各分數段人數:課程ID和課程名稱
思路:case表達式的用法
select Course.c_id, Course.c_name,
sum(case when Score.s_score between 85 and 100 then 1 else 0 end) as '優秀',
sum(case when Score.s_score between 70 and 85 then 1 else 0 end) as '良好',
sum(case when Score.s_score between 60 and 70 then 1 else 0 end) as '及格',
sum(case when Score.s_score<60 then 1 else 0 end) as '不及格'
from Score join Course on Score.c_id=Course.c_id
group by c_id,c_name;
*24、查詢學生平均成績及其名次
思路:名次排序使用rank按平均成績降序排序
select s_id, avg(s_score), rank() over (order by avg(s_score) DESC)
from Score
group by s_id;
*25、查詢各科成績前三名的記錄(不考慮成績并列情況)
思路:從排序好名次的表中取數據,因不考慮并列,因此使用row_number進行排序
select c_id, s_score
from (select *, row_number () over (partition by c_id order by s_score DESC) as a from Score) as b
where a in(1,2,3);
26、查詢每門課程被選修的學生數
select c_id, count(s_id)
from Score
group by c_id;
27、查詢出只選修了兩門課程的全部學生的學號和姓名
select Student.s_id,Student.s_name, count(Score.c_id)
from Student join Score on Student.s_id= Score.s_id
group by s_id,s_name
having count(c_id)=2;
28、查詢男生、女生人數
思路:按性別進行分組,分別計算不同分組的性別數
select s_sex, count(s_sex)
from Student
group by s_sex;
29、查詢名字中含有“風”字的學生信息
select *
from Student
where s_name like '%風%';
30、查詢同名同姓學生名單并統計同名人數
思路:按學生姓名進行分組,然后查詢每組人數,若同名同姓,則分組中人數會大于1
select s_name, count(s_id)
from Student
group by s_name
having count(s_id)>1;
31、1990年出生的學生名單(注:Student表中s_birth列的類型是datetime)
思路:可以用like取出相關年份,也可以用year
-- 方法一
select s_name
from Student
where s_birth like '1990%';
-- 方法二
select s_name
from Student
where year(s_birth)=1990;
32、查詢平均成績大于85的所有學生的學號、姓名和平均成績
思路:按學生進行分組
select Student.s_id, Student.s_name, avg(Score.s_score)
from Student join Score on Student.s_id=Score.s_id
group by s_id,s_name
having avg(Score.s_score) >85;
33、查詢每門課程的平均成績,結果按平均成績升序排序,平均成績相同時,按課程號降序排列
select c_id, avg(s_score)
from Score
group by c_id
order by avg(s_score),c_id DESC;
34、查詢課程名稱為“數學”且分數低于60的學生姓名和分數
select Student.s_name, Score.s_score
from Student join Score on Student.s_id=Score.s_id
join Course on Course.c_id=Score.c_id
where Course.c_name='數學'
and Score.s_score <60;
35、查詢所有學生的選課情況
select Student.s_id, Student.s_name, Course.c_id, Course.c_name
from Student join Score on Student.s_id=Score.s_id
join Course on Score.c_id=Course.c_id
group by Student.s_id, Student.s_name, Course.c_id, Course.c_name;
36、查詢任何一門課程成績在70分以上的姓名、課程名稱和分數
select Student.s_name,Course.c_name,Score.s_score
from Student join Score on Student.s_id=Score.s_id
join Course on Score.c_id=Course.c_id
where s_score >70
group by Student.s_name,Course.c_name,Score.s_score;
37、查詢不及格的課程并按課程號從大到小排列
select Score.c_id, Course.c_name,Score.s_id,Student.s_name
from Score join Course on Score.c_id=Course.c_id
join Student on Student.s_id=Score.s_id
where Score.s_score<60
order by c_id DESC;
38、查詢課程編號為03且課程成績在80分以上的學生的學號和姓名
select Student.s_id,Student.s_name
from Student join Score on Student.s_id=Score.s_id
where Score.c_id='03'
and Score.s_score>80;
39、查詢選了課程的學生人數
select c_id,count(s_id)
from Score
group by c_id;
*40、查詢選修“張三”老師所授課程的學生中成績最高的學生姓名及其成績
思路:查出張三老師教了哪些學生,然后把這些學生的成績進行排序,選擇第一名
select Student.s_name, Score.s_score
from Student join Score on Student.s_id=Score.s_id
where Score.s_id in
(select Score.s_id from Score join Course on Score.c_id=Course.c_id
join Teacher on Course.t_id=Teacher.t_id
where t_name='張三')
order by Score.s_score DESC
limit 1;
41、查詢各個課程及相應的選修人數
select c_id, count(s_id)
from Score
group by c_id;
*42、查詢不同課程成績相同的學生的學生編號、課程編號、學生成績
思路:不同課程說明c_id不同
select distinct a.s_id,a.c_id,a.s_score
from Score a join Score b
on a.s_id=b.s_id and a.c_id<> b.c_id
where a.s_score=b.s_score;
43、查詢每門課程成績最好的前兩名
select s_id, c_id, s_score
from (select *,rank() over (partition by c_id order by s_score DESC) as b from Score) as a
where b in (1,2);
44、統計每門課程的學生選修人數(超過5人的課程才統計)。要求輸出課程號和選修人數,查詢結果按人數降序排序,若人數相同,按課程號升序排序
select c_id, count(s_id)
from Score
group by c_id
having count(s_id)>5
order by count(s_id) DESC,c_id;
45、查詢至少選修兩門課程的學生學號
select s_id
from Score
group by s_id
having count(c_id)>=2;
46、查詢選修了全部課程的學生信息
思路:該學生的選修課數量等于可供選擇的所有選修課數量之和
select Student.s_id, Student.s_name,Student.s_birth, Student.s_sex
from Student join Score on Student.s_id=Score.s_id
group by Student.s_id, Student.s_name,Student.s_birth, Student.s_sex
having count(Score.c_id)=(select count(distinct c_id) from Score);
47、查詢沒學過“張三”老師講授的任一門課程的學生姓名
select s_name
from Student
where s_id not in
(select Score.s_id from Score join Course on Score.c_id=Course.c_id
join Teacher on Teacher.t_id=Course.t_id
where t_name = '張三');
48、查詢兩門以上不及格課程的同學的學號及其平均成績
select s_id, avg(s_score)
from Score
where s_score <60
group by s_id
having count(c_id)>=2;
49、檢索課程編號為“04”且分數小于60的學生學號,結果按按分數降序排列
select s_id
from Score
where c_id='04'
and s_score <60
order by s_score DESC;
50、刪除學生編號為“02”的課程編號為“01”的成績
delete from Score
where s_id='02'
and c_id='01';