SQL筆試50題


工具:Navicat Premium 封裝的mysql。

1.表的創建

-- 創建數據庫
create database school;
use school;

-- 建表
-- 學生表:學生編號,學生姓名, 出生年月,學生性別
create table Student(s_id varchar(10),s_name nvarchar(10),s_birth datetime,s_sex nvarchar(10));
insert into Student values('01' , N'趙雷' , '1990-01-01' , N'');
insert into Student values('02' , N'錢電' , '1990-12-21' , N'');
insert into Student values('03' , N'孫風' , '1990-05-20' , N'');
insert into Student values('04' , N'李雲' , '1990-08-06' , N'');
insert into Student values('05' , N'周梅' , '1991-12-01' , N'');
insert into Student values('06' , N'吳蘭' , '1992-03-01' , N'');
insert into Student values('07' , N'鄭竹' , '1989-07-01' , N'');
insert into Student values('08' , N'王菊' , '1990-01-20' , N'');
-- 課程表:課程編號, 課程名稱, 教師編號
create table Course(c_id varchar(10),c_name nvarchar(10),t_id varchar(10));
insert into Course values('01' , N'語文' , '02');
insert into Course values('02' , N'數學' , '01');
insert into Course values('03' , N'英語' , '03');
-- 教師表:教師編號,教師姓名
create table Teacher(t_id varchar(10),t_name nvarchar(10));
insert into Teacher values('01' , N'張三');
insert into Teacher values('02' , N'李四');
insert into Teacher values('03' , N'王五');
-- 成績表:學生編號,課程編號,分數
create table Score(s_id varchar(10),c_id varchar(10),s_score decimal(18,1));
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);

2.表的結構

 

 

3.筆試50題

-- 1.查詢“01”課程比“02”課程成績高的所有學生的學號
SELECT st.*, sc1.s_score as "課程1", sc2.s_score as "課程2", sc3.s_score as "課程3"
From student st 
    JOIN score sc1 on st.s_id=sc1.S_id AND sc1.c_id = "01"
    JOIN score sc2 on st.s_id=sc2.S_id AND  sc2.c_id = "02"
    JOIN score sc3 on st.s_id=sc3.S_id AND sc3.c_id ="03"
WHERE sc1.s_score>sc2.s_score

-- 2.查詢平均成績大於60分的同學的學號和平均成績
SELECT st.s_id,s_name,ROUND(AVG(s_score),2) as avg_score
FROM student st JOIN score on st.s_id = score.s_id
GROUP BY s_id HAVING avg(s_score)>=60
#HAVING子句給出了選擇組的條件;where作用於基本表或視圖,having作用於組;WHERE子句中不能用聚集函數做條件表達式

-- 3.查詢所有同學的學號、姓名、選課數、總成績
SELECT st.s_id,st.s_name,count(c_id) as "選課總數",sum(s_score) as total_score
from student st left join score on st.s_id=score.s_id
GROUP BY st.s_id
#有學生未出現在成績表上,用左連接,保證出現在學生表的學生都被輸出

-- 4.查詢姓“李”的老師的個數
SELECT count(t_id) from teacher where t_name like '李%'

-- 5.查詢沒學過“張三”老師課的同學的學號、姓名
SELECT st1.* 
from student st1 where s_id not in 
    (SELECT st.s_id
    from student st,score sc,course c,teacher te
    WHERE st.s_id = sc.s_id and sc.c_id = c.c_id and c.t_id = te.t_id and     te.t_name =     "張三")

-- 6.查詢學過“張三”老師所教的課的同學的學號、姓名;
SELECT st.* 
from student st 
    join score on st.s_id = score.s_id
    join course on score.c_id = course.c_id
    join teacher on course.t_id = teacher.t_id AND teacher.t_name = "張三"        

SELECT  st.* 
from student st,score sc,course c,teacher te
WHERE st.s_id = sc.s_id and sc.c_id = c.c_id and c.t_id = te.t_id and te.t_name = "張三"

-- 7.查詢學過編號“01”並且也學過編號“02”課程的同學的學號、姓名;
SELECT st.* 
from student st 
    join score sc1 on st.s_id = sc1.s_id and sc1.c_id = 01
    join score sc2 on st.s_id = sc2.s_id and sc2.c_id = 02 

-- 8.查詢學過01但是沒有學過02的同學的信息
SELECT st.* 
from student st join score s1 on st.s_id = s1.s_id and s1.c_id = 01 
where st.s_id not in (SELECT  s_id from  score WHERE c_id = 02)
#字段前最好都跟上表名

-- 9.查詢所有課程成績小於60分的同學的學號、姓名;
SELECT st.s_id,s_name
from student st 
WHERE s_id in(
    SELECT s_id from score 
    GROUP BY s_id HAVING max(s_score)<60
    ) 

-- 10.查詢沒有學全所有課的同學的學號、姓名
select * from student 
where s_id not in(
    SELECT s_id from score 
    GROUP BY s_id HAVING count(c_id) = (
        select count(c_id) from course
        )
    )

-- 11.查詢至少有一門課與學號為“01”的同學所學相同的同學的學號和姓名
SELECT st.* 
from student st 
where s_id  in (
    SELECT s_id from score where c_id in(
        SELECT c_id from score WHERE s_id = 01
        ) and s_id not in ("01")
    )

#思路類似,但將所有表放在一起可以精簡過程
SELECT DISTINCT st.* 
FROM student st JOIN score sc 
    ON st.s_id=sc.s_id AND sc.c_id IN (
        SELECT sc.c_id FROM score sc WHERE sc.s_id="01" 
    ) AND sc.s_id NOT IN ("01");

-- 12.查詢和"01"號的同學學習的課程完全相同的其他同學的學號和姓名
SELECT st.* 
from student st join score sc on st.s_id = sc.s_id
WHERE st.s_id not in (
    SELECT s_id from student WHERE c_id not in(
        SELECT c_id from score where s_id = "01"
    )
)
GROUP BY st.s_id
HAVING COUNT(c_id)=(SELECT count(c_id) from score WHERE s_id = "01")
#虛擬表的名稱為局部變量

-- 14.查詢沒學過"張三"老師講授的任一門課程的學生姓名
SELECT s_name from student  WHERE s_id not in(
    SELECT st.s_id  FROM student st 
            join score sc on st.s_id = sc.s_id
        join course c on sc.c_id = c.c_id
            join teacher te on te.t_id = c.t_id and t_name = "張三"
    )

-- 15.查詢兩門及其以上不及格課程的同學的學號,姓名及其平均成績
SELECT st.s_id,s_name,ROUND(avg(sc.s_score),2) as avg_score
from student st join score sc on st.s_id = sc.s_id
WHERE st.s_id in (
    SELECT s_id from score WHERE s_score < "60"
    GROUP BY s_id 
    HAVING COUNT(*)> 1
)
GROUP BY st.s_id

#有分組匯總函數就要有group by,除非只有一個組
SELECT st.s_id,st.s_name,ROUND(avg(sc.s_score),2) as avg_score
from student st 
    join score sc on st.s_id = sc.s_id and sc.s_score<'60'
GROUP BY s_id HAVING count(s_score) > 1

-- 16.檢索"01"課程分數小於60,按分數降序排列的學生信息
SELECT st.* from student st JOIN score sc on st.s_id = sc.s_id
WHERE sc.s_score < 60 and sc.c_id = "01"
ORDER BY sc.s_score DESC

-- 17.按平均成績從高到低顯示所有學生的平均成績
SELECT st.s_id, st.s_name,sc1.s_score as "01",sc2.s_score as "02",sc3.s_score as "03",ROUND(avg(sc.s_score),2) as "avg_score"
from student st 
    left join score sc on st.s_id = sc.s_id 
    left join score sc1 on st.s_id = sc1.s_id and sc1.c_id = "01"
    left join score sc2 on st.s_id = sc2.s_id and sc2.c_id = "02"
    left join score sc3 on st.s_id = sc3.s_id and sc3.c_id = "03" 
GROUP BY st.s_id
ORDER BY avg(sc.s_score) DESC;

-- 18.查詢各科成績最高分、最低分和平均分:以如下形式顯示:課程ID,課程name,最高分,最低分,平均分,及格率
SELECT a.c_id "課程ID",a.c_name "課程名",
    max(b.s_score) "最高分",
    min(b.s_score) "最低分",
    ROUND(avg(b.s_score),2)  "平均分",
    sum(case when b.s_score>60 then 1 else 0 end)/count(1) "及格率",
    sum(case when b.s_score>=70 and b.s_score < 80 then 1 else 0 end)/count(1) "中等率",
    sum(case when b.s_score>=80 and b.s_score < 90 then 1 else 0 end)/count(1) "優良率",
    sum(case when b.s_score>=90 then 1 else 0 end)/count(1) "優秀率"
from course a join score b on a.c_id = b.c_id
GROUP BY 1

-- 19.按各科平均成績從低到高和及格率的百分數從高到低順序
SELECT sc.c_id,c_name,round(avg(s_score),2) 'avg_score',
    concat(round(sum(case when s_score >= 60 then 1 else 0 end)/count(1)*100,2),'%') "及格率"
from score sc join course c on sc.c_id = c.c_id
GROUP BY sc.c_id
ORDER BY avg_score,"及格率" desc

-- 20.查詢學生的總成績並進行排名
--有rank函數時
SELECT sc.s_id,st.s_name,sum(s_score) as sum_score,
    rank() over(ORDER BY sum(sc.s_score) desc) as score_rank
FROM score sc join student st on sc.s_id = st.s_id 
GROUP BY sc.s_id;

--無rank函數時
SELECT a.s_id,a.s_name,
    @i := @i +1 as 序號,
    @k := (case when  @score = a.total_score then  @k else @i end) as 排名,
    @score := a.total_score as total_score
from(
    SELECT st.s_id ,s_name ,sum(sc.s_score) as total_score
    from student st join score sc on st.s_id = sc.s_id 
    GROUP BY st.s_id
    ORDER BY total_score desc
    )a,
    (SELECT @i:=0,@k:=0,@score:=0)b 
    
-- 21.查詢不同老師所教不同課程平均分從高到低顯示
SELECT t.t_id,t_name,c.c_id,c.c_name,
    round(avg(s_score),2) avg_score
from teacher t 
    join course c on t.t_id = c.t_id 
    join score sc on c.c_id=sc.c_id
GROUP BY t_id,c_id
ORDER BY avg_score desc

-- 22.查詢所有課程的成績第2名到第3名的學生信息及該課程成績
--row_number 分數相同的兩個人的名次按順序確定
SELECT st.*,c.c_id,c.c_name,s.myrank
from student st 
    join (SELECT s_id,c_id,ROW_NUMBER() over(partition BY score.c_id order by s_score desc) as myrank from score ) s on st.s_id=s.s_id
    join course c on s.c_id = c.c_id
WHERE myrank in (2,3)

-- 或者自己寫,即如果存在並列排名的情況,單個課程代碼如下,多個課程的連接有點問題
SELECT st.*,sc.c_id,c_name,s_score,myrank
FROM student st 
    join score sc on st.s_id=sc.s_id and c_id = '03'
    join course c on sc.c_id=c.c_id
    join (SELECT s_id,c_id,
        @i:=@i+1,
        @k:=(case when @score=s_score then @k else @i end) myrank,
        @score:=s_score
        from score sc
            join (SELECT @i:=0,@k:=0,@score:=0)b on sc.c_id='03'
        ORDER BY s_score desc
        )a on sc.s_id = a.s_id
WHERE myrank<4

-- 23.統計各科成績各分數段人數:課程編號,課程名稱,[100-85],[85-70],[70-60],[0-60]及所占百分比
SELECT c.c_id,c_name,
    sum(case when s_score<60 then 1 else 0 end)/count(s_score) as "[0-60]比例",
    sum(case when s_score<60 then 1 else 0 end) as "[0-60]人數",
    sum(case when s_score<70 and s_score>=60 then 1 else 0 end)/count(s_score) as '[60-70]比例',
    sum(case when s_score<70 and s_score>=60 then 1 else 0 end) as '[60-70]人數',
    sum(case when s_score<85 and s_score>=70 then 1 else 0 end)/count(s_score) as '[70-85]比例',
    sum(case when s_score<85 and s_score>=70 then 1 else 0 end) as '[70-85]人數',
    sum(case when s_score>=85 then 1 else 0 end)/count(s_score) as '[85-100]比例',
    sum(case when s_score>=85 then 1 else 0 end) as '[85-100]人數'
from score sc join course c on sc.c_id = c.c_id
GROUP BY c_id

-- 24.查詢學生平均成績及其名次
SELECT st.s_id,s_name,round(avg(s_score),2) as avg_score,
    rank() over(ORDER BY avg(s_score) desc) as avg_rank
from student st join score sc on st.s_id=sc.s_id 
GROUP BY s_id

-- 25.查詢各科成績前三名的記錄
SELECT * from(
    SELECT  st.s_id,s_name,sc.c_id,c_name,s_score,
        ROW_NUMBER() over(partition BY sc.c_id order by s_score desc) as myrank
    from student st 
        JOIN score sc on st.s_id = sc.s_id
         join course c on sc.c_id = c.c_id
    GROUP BY c_id,s_id) t
WHERE myrank < 4

-- 26.查詢每門課程被選修的學生數
SELECT sc.c_id,c_name,count(sc.s_id)
FROM score sc join course c on sc.c_id=c.c_id
GROUP BY c_id 

-- 27.查詢出只選修了一門課程的全部學生的學號和姓名
SELECT st.s_id,s_name c_name
from student st 
    right JOIN score sc on st.s_id=sc.s_id
    join course c on sc.c_id=c.c_id
GROUP BY sc.c_id HAVING COUNT(st.s_id)=1

-- 28.查詢男生、女生人數
SELECT s_sex,count(s_id) from student GROUP BY s_sex 

-- 29.查詢名字中含有"風"字的學生信息
SELECT * from student  WHERE s_name LIKE '%風%';

-- 30.查詢同名同性學生名單,並統計同名人數
SELECT s_id,s_name,count(s_id) from student GROUP BY s_name,s_sex 

-- 31.查詢1990年出生的學生名單(注:Student表中Sage列的類型是datetime)
SELECT s_id,s_name,s_birth from student WHERE YEAR(s_birth)=1990

-- 32.查詢每門課程的平均成績,結果按平均成績升序排列,平均成績相同時,按課程號降序排列
SELECT sc.c_id, c_name, round(avg(s_score),2) as avg_score
from score sc join course c on sc.c_id = c.c_id 
GROUP BY c_id 
ORDER BY avg_score ,c_id desc

-- 33.查詢不及格的課程,並按課程號從大到小排列
SELECT sc.c_id,c_name,sc.s_id,s_score
from score sc join course c on sc.c_id=c.c_id
WHERE s_score<60
ORDER BY sc.c_id desc

-- 34.查詢課程編號為"01"且課程成績在60分以上的學生的學號和姓名
SELECT st.s_id ,s_name,s_score 
from student st join score sc on st.s_id = sc.s_id 
WHERE s_score > 60 and sc.c_id = 01

-- 35.查詢所有學生的課程及分數情況
SELECT * from(
    SELECT st.s_id ,s_name ,sc.c_id,c_name,s_score 
    from student st 
        left join score sc on st.s_id = sc.s_id
        JOIN course c on sc.c_id = c.c_id
        ) tb PIVOT(sum(s_score) for c_name in ([語文],[數學],[英語])) t
-- mysql不支持pivot函數轉換

-- 36.查詢任何一門課程成績在70分以上的姓名、課程名稱和分數
SELECT s_name,c_name,s_score
from student st 
    join score sc on st.s_id = sc.s_id
    JOIN course c on sc.c_id = c.c_id
WHERE st.s_id not in(SELECT s_id from score WHERE s_score<=70)

-- 37.查詢課程名稱為"數學",且分數低於60的學生姓名和分數
SELECT s_name,s_score
from student st 
    join score sc on st.s_id = sc.s_id and s_score<60
    JOIN course c on c.c_id = sc.c_id and c_name='數學' 

-- 38.查詢課程編號為03且課程成績在80分以上的學生的學號和姓名
SELECT st.s_id,s_name
FROM student st 
    JOIN score sc on st.s_id = sc.s_id and sc.c_id=03 and s_score>80

-- 39.求每門課程的學生人數
SELECT c_id,count(s_score) as '學生人數' from score GROUP BY c_id

-- 40.查詢選修“張三”老師所授課程的學生中,成績最高的學生姓名及其成績
SELECT  s_name,s_score
from student st 
    JOIN score sc on st.s_id=sc.s_id
    JOIN course c on sc.c_id = c.c_id
    join teacher t on c.t_id = t.t_id and t_name='張三'
ORDER BY s_score desc LIMIT 0,1
#mysql 沒有top語句

-- 41.查詢不同課程成績相同的學生的學生編號、課程編號、學生成績
SELECT s_id,c_id,s_score
from score
WHERE s_score in(
    SELECT s_score from score GROUP BY s_score HAVING count(s_id)>1
    )

-- 42.查詢每門功課成績最好的前兩名
SELECT * from(
    SELECT st.s_id,s_name,sc.c_id,c_name,s_score,
         ROW_NUMBER() over(partition BY sc.c_id order by s_score desc) as myrank
    from student st 
        join score sc on st.s_id = sc.s_id
        join course c on sc.c_id=c.c_id
        ) a
WHERE myrank<3

-- 43.統計每門課程的學生選修人數(超過5人的課程才統計)。要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列
SELECT sc.c_id,count(s_id) as '選修人數'
from score sc 
GROUP BY c_id HAVING count(s_id)>5
ORDER BY '選修人數' desc,c_id asc

-- 44.檢索至少選修兩門課程的學生學號
SELECT s_id,count(c_id) as '選修課程數' from score GROUP BY s_id HAVING count(c_id)>1

-- 45.查詢選修了全部課程的學生信息
SELECT st.*
from student st JOIN score sc on st.s_id = sc.s_id
GROUP BY s_id HAVING count(c_id) =
    (SELECT count(DISTINCT c_id) from score)

-- 46.查詢各學生的年齡
SELECT s_id,s_name,(YEAR(sysdate())-YEAR(s_birth)) as s_age from student

--47.查詢本周過生日的學生
SELECT * from student WHERE WEEKOFYEAR(now())-WEEKOFYEAR(s_birth)=0
SELECT WEEKOFYEAR(now())

-- 48.查詢下周過生日的學生
SELECT * from student WHERE WEEKOFYEAR(now())-WEEKOFYEAR(s_birth)=-1

-- 49.查詢本月過生日的學生
SELECT * from student WHERE month(now())-MONTH(s_birth)=0

-- 50.查詢下月過生日的學生
SELECT * from student WHERE month(now())-MONTH(s_birth)=-1

 推薦相關博客:https://cloud.tencent.com/developer/article/1586076


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM