MySQL 50題 精練 + 小總結

目錄面試

1、數據表信息算法

2、建立數據庫、表、填充信息sql

一、建立數據庫並使用數據庫

二、建立學生表並插入數據設計模式

三、建立教師表並插入數據架構

四、建立課程表並插入數據機器學習

五、建立成績表並插入數據函數

3、精簡50題 及 參考答案oop


免費贈送】我的整理關於MySQL知識的思惟導圖:MySQL_思惟導圖(全面).xmind.zip學習

免費贈送】我的整理關於MySQL索引的PPT:MySQL索引原理及如何創建高效索引.pptx

1、數據表信息

已知有如下4張表:

數據庫、表信息說明
序號 表名稱 字段信息 描述
1 學生表 student(s_id,  s_name,  s_birth,  s_sex) 學號,  學生姓名,  出生年月,  性別
2 成績表 score(s_id,  c_id,  score) 學號,  課程號,  成績
3 課程表 course(c_id,  c_name,  t_id) 課程號,  課程名稱,  教師號
4 教師表 teacher(t_id,  t_name) 教師號,  教師姓名

以上4個表是經過有加粗的字段創建鏈接的。


2、建立數據庫、表、填充信息

一、建立數據庫並使用

【注意】:推薦庫名與應用名稱保持一致

-- 學校考試成績庫。庫名與應用名稱保持一致
DROP DATABASE IF EXISTS school_score;
CREATE DATABASE school_score;
-- 使用學校考試成績庫
USE school_score; 

二、建立學生表並插入數據

【注意】:

  1. 表必備三個字段,id、create_time、update_time
  2. 表名、字段名必段使用小寫字母或數字,禁止出現數字開頭,禁止兩個下劃線中間只出現數字。數據庫字段名的修改代價很大,由於沒法進行預發佈,因此字段名稱須要慎重考慮
  3. 表名不使用複數名詞

說明:其中 id 必爲主鍵,類型爲bigint unsigned、單表時自增、步長爲1。create_time,update_time的類型均爲 datetime 類型,前者如今時表示主動式建立,後者過去分詞表示被動式更新。

-- 建立學生表
CREATE TABLE IF NOT EXISTS `student`(
    `id` BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主鍵',
    `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
    `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
  	
    `s_id` VARCHAR(20) COMMENT '學生編號',
    `s_name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '學生姓名',
    `s_birth` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '出生年月',
    `s_sex` ENUM('男', '女') NOT NULL DEFAULT '男' COMMENT '學生性別',
    PRIMARY KEY(`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 插入學生表測試數據
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('01' , '趙雷' , '1990-01-01' , '男');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('02' , '錢電' , '1990-12-21' , '男');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('03' , '孫風' , '1990-05-20' , '男');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('04' , '李雲' , '1990-08-06' , '男');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('05' , '周梅' , '1991-12-01' , '女');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('06' , '吳蘭' , '1992-03-01' , '女');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('07' , '鄭竹' , '1989-07-01' , '女');
INSERT INTO student (`s_id`, `s_name`, `s_birth`, `s_sex`) VALUES ('08' , '王菊' , '1990-01-20' , '女');

三、建立教師表並插入數據

-- 教師表
CREATE TABLE `teacher`(
    id BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主鍵',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
    
    `t_id` VARCHAR(20) COMMENT '教師編號',
    `t_name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '教師姓名',
    PRIMARY KEY(`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 教師表測試數據
INSERT INTO teacher (`t_id`, `t_name`) VALUES('01' , '張老師');
INSERT INTO teacher (`t_id`, `t_name`) VALUES('02' , '李老師');
INSERT INTO teacher (`t_id`, `t_name`) VALUES('03' , '王老師');

四、建立課程表並插入數據

-- 課程表
CREATE TABLE `course`(
    `id` BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主鍵',
    `create_time` DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
    `update_time` DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
    
    `c_id`  VARCHAR(20) COMMENT '課程編號',
    `c_name` VARCHAR(20) NOT NULL DEFAULT '' COMMENT '課程名稱',
    `t_id` VARCHAR(20) NOT NULL COMMENT '教師編號',
    PRIMARY KEY(`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

-- 課程表測試數據
INSERT INTO course (`c_id`, `c_name`, `t_id`) VALUES('01' , '語文' , '02');
INSERT INTO course (`c_id`, `c_name`, `t_id`) VALUES('02' , '數學' , '01');
INSERT INTO course (`c_id`, `c_name`, `t_id`) VALUES('03' , '英語' , '03');

五、建立成績表並插入數據

-- 成績表
CREATE TABLE `score`(
    id BIGINT UNSIGNED AUTO_INCREMENT COMMENT '主鍵',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '建立時間',
    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新時間',
    
    `s_id` VARCHAR(20) COMMENT '學生編號',
    `c_id`  VARCHAR(20) COMMENT '課程編號',
    `s_score` INT(3) COMMENT '分數',
    PRIMARY KEY(id)
) ENGINE=INNODB DEFAULT CHARSET=utf8;
 
-- 成績表測試數據
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('01' , '01' , 80);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('01' , '02' , 90);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('01' , '03' , 99);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('02' , '01' , 70);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('02' , '02' , 60);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('02' , '03' , 80);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('03' , '01' , 80);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('03' , '02' , 80);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('03' , '03' , 80);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('04' , '01' , 50);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('04' , '02' , 30);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('04' , '03' , 20);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('05' , '01' , 76);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('05' , '02' , 87);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('06' , '01' , 31);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('06' , '03' , 34);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('07' , '02' , 89);
INSERT INTO score (`s_id`, `c_id`, `s_score`) VALUES('07' , '03' , 98);

數據狀況截圖說明:

上述建立庫及表的腳本文件下載:MySQL 精簡50題練習 school_score.sql


3、精簡50題 及 參考答案

一、查詢"01"課程比"02"課程成績高的學生的學號及課程分數

-- 一、查詢"01"課程比"02"課程成績高的學生的學號及課程分數
SELECT a.s_id AS s_id, score1, score2
FROM 
(SELECT s_id, s_score AS score1 FROM score WHERE c_id = '01') a
INNER JOIN
(SELECT s_id, s_score AS score2 FROM score WHERE c_id = '02') b
ON a.s_id = b.s_id WHERE score1 > score2;

運行結果截圖: 


二、查詢"01"課程比"02"課程成績高的學生的信息及課程分數

-- 二、查詢"01"課程比"02"課程成績高的學生的信息及課程分數
SELECT s.*, a.s_score AS score1, b.s_score AS score2
FROM student s,
     (SELECT s_id,s_score FROM score WHERE c_id = '01') a,
     (SELECT s_id,s_score FROM score WHERE c_id = '02') b
WHERE a.s_id = b.s_id AND a.s_score > b.s_score AND s.`s_id` = a.s_id;

運行結果截圖: 


三、查詢平均成績大於等於60分的同窗的學生編號和學生姓名和平均成績

-- 三、查詢平均成績大於等於60分的同窗的學生編號和學生姓名和平均成績
SELECT s.`s_id`,s.`s_name`,AVG(s_score) AS avg_score 
FROM student AS s,score AS sc
WHERE s.`s_id` = sc.`s_id` 
GROUP BY s.`s_id`
HAVING avg_score >= 60;

運行結果截圖: 


四、查詢全部同窗的學生編號、學生姓名、選課總數、全部課程的總成績(沒成績顯示null)

這道題得用到left join,不能用where鏈接,由於題目說了要求有顯示爲null的,where是inner join,不會出現null,若是用where在這道題裏會查不出第08號學生

-- 四、查詢全部同窗的學生編號、學生姓名、選課總數、全部課程的總成績(沒成績顯示null)
SELECT s.`s_id`,s_name,COUNT(c_id)AS 選課總數,SUM(s_score) AS 總成績
FROM student s
LEFT JOIN score sc
ON s.`s_id` = sc.`s_id`
GROUP BY s_id;

運行結果截圖: 


五、查詢姓「李」的老師的個數

-- 五、查詢姓「李」的老師的個數
SELECT COUNT(t_name) AS 人數
FROM teacher 
WHERE t_name LIKE '李%';

運行結果截圖: 


六、查詢沒學過「張三」老師課的學生的學號、姓名

-- 六、查詢沒學過「張老師」老師課的學生的學號、姓名
SELECT s_id, s_name FROM student WHERE s_id NOT IN
(SELECT s_id FROM score WHERE c_id IN
(SELECT c_id FROM course WHERE t_id IN 
(SELECT t_id 
FROM teacher 
WHERE t_name = '張老師')));

-- 法二
SELECT s_id, s_name 
FROM student
WHERE s_id NOT IN(SELECT sc.s_id FROM score sc
INNER JOIN course co ON sc.`c_id` = co.`c_id`
INNER JOIN teacher te ON co.`t_id`= te.`t_id`
WHERE te.`t_name`='張老師');

-- 法三
SELECT s_id, s_name
FROM student
WHERE s_name NOT IN (
    SELECT s.s_name
    FROM student AS s, course AS c, teacher AS t, score AS sc
    WHERE s.s_id = sc.s_id
        AND sc.c_id = c.c_id
        AND c.t_id = t.t_id
        AND t.t_name = '張老師');

運行結果截圖: 


七、查詢學過編號爲「01」的課程而且也學過編號爲「02」的課程的學生的學號、姓名

-- 七、查詢學過編號爲「01」的課程而且也學過編號爲「02」的課程的學生的學號、姓名
SELECT s_id, s_name 
FROM student 
WHERE s_id IN (
SELECT s_id
FROM score
WHERE c_id = '01' OR c_id = '02'
GROUP BY s_id
HAVING COUNT(c_id) >= 2);

運行結果截圖: 


八、查詢課程編號爲「02」的總成績

--  八、查詢課程編號爲「02」的總成績
SELECT SUM(s_score) AS 總成績
FROM score
WHERE c_id = '02';

運行結果截圖: 


九、查詢沒有學全全部課的學生的學號、姓名

-- 九、查詢沒有學全全部課的學生的學號、姓名
SELECT st.`s_id`,st.`s_name` 
FROM student st
INNER JOIN score sc
ON st.`s_id` = sc.`s_id`
GROUP BY sc.`s_id`
HAVING COUNT(sc.`c_id`) < (SELECT
COUNT(DISTINCT c_id) 
FROM course);

運行結果截圖: 


十、查詢至少有一門課與學號爲「01」的學生所學課程相同的學生的學號和姓名

-- 十、查詢至少有一門課與學號爲「01」的學生所學課程相同的學生的學號和姓名
SELECT st.`s_id`,st.`s_name`
FROM student st 
WHERE st.`s_id` IN(
SELECT DISTINCT sc.`s_id` 
FROM score sc
WHERE sc.`c_id` IN(
SELECT sc.`c_id`
FROM score sc
WHERE sc.`s_id` = 01)) AND
st.`s_id` <> '01';

-- 法二
SELECT DISTINCT st.`s_id`,st.`s_name`
FROM student st 
INNER JOIN score sc
ON st.`s_id`= sc.`s_id`
WHERE sc.`c_id` IN(
SELECT sc.`c_id`
FROM score sc
WHERE sc.`s_id` = '01') AND
st.`s_id` <> '01';

運行結果截圖: 


十一、查詢和「01」號同窗所學課程徹底相同的其餘同窗的信息

-- 十一、查詢和「01」號同窗所學課程徹底相同的其餘同窗的信息
SELECT DISTINCT st.* 
FROM student st
INNER JOIN score sc
ON st.`s_id` = sc.`s_id`
WHERE sc.`c_id` IN
(SELECT sc.`c_id`
FROM score sc
WHERE sc.`s_id`= '01') AND  sc.`s_id` <> '01'
GROUP BY sc.`s_id`
HAVING COUNT(sc.`c_id`) = (SELECT
COUNT(c_id) FROM score WHERE s_id = '01');

運行結果截圖: 


十二、查詢兩門及其以上不及格課程的同窗的學號,姓名及其平均成績

-- 十二、查詢兩門及其以上不及格課程的同窗的學號,姓名及其平均成績
SELECT st.`s_id`,st.`s_name`,AVG(sc.s_score) AS avg_score
FROM student st, score sc 
WHERE st.`s_id` = sc.`s_id`
AND sc.`s_score` < 60
GROUP BY sc.`s_id`
HAVING COUNT(sc.`c_id`) >= 2;

運行結果截圖:


1三、檢索"01"課程分數小於60,按分數降序排列的學生信息

-- 1三、檢索"01"課程分數小於60,按分數降序排列的學生信息
SELECT st.*,sc.`s_score`
FROM student st
INNER JOIN score sc ON 
st.`s_id`= sc.`s_id` 
WHERE sc.`c_id` = '01' AND sc.`s_score` < 60
ORDER BY sc.`s_score` DESC;

運行結果截圖:


1四、按平均成績從高到低顯示全部學生的全部課程的成績以及平均成績

-- 1四、按平均成績從高到低顯示全部學生的全部課程的成績以及平均成績
SELECT s_id, 
SUM(CASE WHEN c_id = '01' THEN s_score ELSE NULL END) AS score1,
SUM(CASE WHEN c_id = '02' THEN s_score ELSE NULL END) AS score2,
SUM(CASE WHEN c_id = '03' THEN s_score ELSE NULL END) AS score3,
AVG(s_score)
FROM score
GROUP BY s_id
ORDER BY AVG(s_score) DESC;

運行結果截圖:


1五、查詢各科成績最高分、最低分、平均分、及格率、中等率、優良率、優秀率

  • 要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列。
  • 以以下形式顯示:課程ID,課程name,最高分,最低分,平均分,及格率,中等率,優良率,優秀率。
  • 及格爲>=60,中等爲:70-80,優良爲:80-90,優秀爲:>=90
--  1五、查詢各科成績最高分、最低分、平均分、及格率、中等率、優良率、優秀率
--      要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列
--      以以下形式顯示:課程ID,課程name,最高分,最低分,平均分,及格率,中等率,優良率,優秀率
--      及格爲>=60,中等爲:70-80,優良爲:80-90,優秀爲:>=90 
-- 先從簡單的寫法開始,及格率直接用小數表示,沒用百分號
SELECT co.c_id AS 課程ID, co.c_name AS 課程名稱, COUNT(*) AS 選修人數, 
   MAX(s_score) AS 最高分 , MIN(s_score) AS 最低分, AVG(s_score) AS 平均分,
   SUM(CASE WHEN s_score >= 60 THEN 1 ELSE 0 END) / COUNT(*) AS  '及格率',
   SUM(CASE WHEN s_score BETWEEN 70 AND 80 THEN 1 ELSE 0 END) / COUNT(*) AS  '中等率',
   SUM(CASE WHEN s_score BETWEEN 80 AND 90 THEN 1 ELSE 0 END) / COUNT(*) AS  '優良率',
   SUM(CASE WHEN s_score >= 90 THEN 1 ELSE 0 END) / COUNT(*) AS  '優秀率'
FROM score sc, course co
WHERE sc.c_id = co.c_id	
GROUP BY co.c_id
ORDER BY COUNT(*) DESC, co.c_id;

-- 複雜點的寫法,及格率用百分號表示
SELECT a.c_id AS '課程ID', course.c_name AS '課程name', COUNT(*) AS 選修人數,
       MAX(a.s_score) AS '最高分',  MIN(a.s_score) AS '最低分',
       CAST(AVG(a.s_score) AS DECIMAL(5,2)) AS '平均分',
       CONCAT(CAST(SUM(pass)/COUNT(*)*100 AS DECIMAL(5,2)),'%') AS '及格率',
       CONCAT(CAST(SUM(medi)/COUNT(*)*100 AS DECIMAL(5,2)),'%') AS '中等率',
       CONCAT(CAST(SUM(good)/COUNT(*)*100 AS DECIMAL(5,2)),'%') AS '優良率',
       CONCAT(CAST(SUM(excellent)/COUNT(*)*100 AS DECIMAL(5,2)),'%') AS '優秀率' 
FROM
    (SELECT * ,
        CASE WHEN s_score>=60 THEN 1 ELSE 0 END AS pass,
        CASE WHEN s_score>=70 AND s_score<80 THEN 1 ELSE 0 END AS medi,
        CASE WHEN s_score>=80 AND s_score<90 THEN 1 ELSE 0 END AS good,
        CASE WHEN s_score>=90 THEN 1 ELSE 0 END AS excellent
     FROM score) a
LEFT JOIN course ON a.c_id=course.c_id
GROUP BY a.c_id
ORDER BY COUNT(*) DESC, a.c_id;

運行結果截圖:


1六、按平均成績進行排序,顯示總排名和各科排名,Score 重複時保留名次空缺

  • Score 重複時保留名次空缺,指的是rank()和dense_rank()的區別,也就是兩個並列第一名以後的那我的是第三名(rank)仍是第二名(dense_rank)的區別。
-- 1六、按平均成績進行排序,顯示總排名和各科排名,Score 重複時保留名次空缺
SELECT s.*, rank_01, rank_02, rank_03, rank_total
FROM student s
LEFT JOIN (SELECT s_id, rank() over(PARTITION BY c_id ORDER BY s_score DESC) AS rank_01 FROM score WHERE c_id=01) A ON s.s_id=A.s_id
LEFT JOIN (SELECT s_id, rank() over(PARTITION BY c_id ORDER BY s_score DESC) AS rank_02 FROM score WHERE c_id=02) B ON s.s_id=B.s_id
LEFT JOIN (SELECT s_id, rank() over(PARTITION BY c_id ORDER BY s_score DESC) AS rank_03 FROM score WHERE c_id=03) C ON s.s_id=C.s_id
LEFT JOIN (SELECT s_id, rank() over(ORDER BY AVG(s_score) DESC) AS rank_total FROM score GROUP BY s_id) D ON s.s_id=D.s_id
ORDER BY rank_total ASC;

運行結果截圖:


1七、按各科成績進行排序,並顯示排名

-- 1七、按各科成績進行排序,並顯示排名
SELECT a.`c_id`,a.`s_id`,a.`s_score`,COUNT(b.`s_score`)+1 AS rank 
FROM score a
LEFT JOIN score b
ON a.`s_score`< b.`s_score` AND a.`c_id`= b.`c_id`
GROUP BY a.`c_id`,a.`s_id`,a.`s_score`
ORDER BY a.`c_id`,rank;

運行結果截圖:


1八、查詢學生的總成績並進行排名

-- 1八、查詢學生的總成績並進行排名
SELECT a.*, @rank:= @rank+1 AS rank 
FROM 
  (SELECT s_id,SUM(s_score)
    FROM score 
    GROUP BY s_id 
    ORDER BY SUM(s_score) DESC) a,
  (SELECT @rank:=0) b;

運行結果截圖:


1九、查詢不一樣老師所教不一樣課程平均分從高到低顯示

-- 1九、查詢不一樣老師所教不一樣課程平均分從高到低顯示
SELECT te.`t_id`, te.`t_name`, AVG(sc.`s_score`)
FROM score sc INNER JOIN course co ON sc.`c_id`= co.`c_id`
INNER JOIN teacher te ON co.`t_id`= te.`t_id`
GROUP BY te.`t_id`
ORDER BY AVG(sc.`s_score`) DESC;

運行結果截圖:


20、查詢全部課程的成績第2名到第3名的學生信息及該課程成績

--  20、查詢全部課程的成績第2名到第3名的學生信息及該課程成績
SELECT result.c_id, result.s_id, result.s_score, student.`s_name`,student.`s_birth`,student.`s_sex`
FROM 
(SELECT *, IF(@pa=a.c_id, @rank:= @rank+1, @rank:=1) AS rank, @pa:=a.c_id
FROM 
(SELECT c_id, s_id, s_score FROM score
GROUP BY c_id, s_id ORDER BY c_id, s_score DESC) a,
(SELECT @rank:=0, @pa:=NULL) b) result
LEFT JOIN student ON result.s_id = student.`s_id`
WHERE rank BETWEEN 2 AND 3
GROUP BY c_id, s_score DESC;

運行結果截圖:


2一、使用分段[100-85],[85-70],[70-60],[<60]來統計各科成績,分別統計各分數段人數:課程ID和課程名稱

--  2一、使用分段[85-100],[70-84],[60-69],[<60]來統計各科成績,分別統計各分數段人數:課程ID和課程名稱
SELECT a.c_id AS '課程編號',course.c_name AS '課程名稱',
SUM(level1) AS '[85-100]人數', SUM(level1)/COUNT(1) AS '[85-100]佔比',
SUM(level2) AS '[70-84]人數', SUM(level2)/COUNT(1) AS '[70-84]佔比',
SUM(level3) AS '[60-69]人數', SUM(level3)/COUNT(1) AS '[60-69]佔比',
SUM(level4) AS '[0-59]人數', SUM(level4)/COUNT(1) AS '[0-59]佔比' FROM
(SELECT *,
(CASE WHEN s_score BETWEEN 85 AND 100 THEN 1 ELSE 0 END) AS 'level1',
(CASE WHEN s_score BETWEEN 70 AND 84 THEN 1 ELSE 0 END) AS 'level2',
(CASE WHEN s_score BETWEEN 60 AND 69 THEN 1 ELSE 0 END) AS 'level3',
(CASE WHEN s_score BETWEEN 0 AND 59 THEN 1 ELSE 0 END) AS 'level4'
FROM score) a
LEFT JOIN course ON a.c_id=course.c_id
GROUP BY a.c_id;

運行結果截圖:


2二、查詢學平生均成績及其名次

-- 2二、查詢學平生均成績及其名次
SELECT a.*,@rank:=@rank+1 AS rank
FROM 
  (SELECT s_id, AVG(s_score) AS '平均成績' 
  FROM score 
  GROUP BY s_id
  ORDER BY AVG(s_score) DESC) a,
  (SELECT @rank:=0) b;

運行結果截圖:


2三、查詢各科成績前三名的記錄

-- 2三、查詢各科成績前三名的記錄
SELECT a.`c_id`,a.`s_id`,a.`s_score`
FROM score a
WHERE
  (SELECT COUNT(b.s_id) FROM score b WHERE a.`c_id`=b.`c_id` AND a.`s_score`< b.`s_score`) < 3
GROUP BY a.`c_id`, a.`s_id`;

運行結果截圖:


2四、查詢每門課程被選修的學生數

-- 2四、查詢每門課程被選修的學生數
SELECT c_id, COUNT(s_id) AS '選修人數'
FROM score
GROUP BY c_id;

運行結果截圖:


2五、 查詢出只有兩門課程的所有學生的學號和姓名

-- 2五、 查詢出只有兩門課程的所有學生的學號和姓名
SELECT s_id,s_name 
FROM student 
WHERE s_id IN(
SELECT s_id 
FROM score 
GROUP BY s_id
HAVING COUNT(c_id)=2);

運行結果截圖:


2六、查詢男生、女生人數

-- 2六、查詢男生、女生人數
SELECT s_sex AS '性別',COUNT(*) AS  '人數'
FROM student
GROUP BY s_sex;

運行結果截圖:


2七、查詢名字中含有"風"字的學生信息

-- 2七、查詢名字中含有"風"字的學生信息
SELECT * 
FROM student 
WHERE s_name LIKE '%風%';

運行結果截圖:


2八、查詢同名同姓學生名單,並統計同名人數

-- 2八、查詢同名同姓學生名單,並統計同名人數
SELECT s_name, num AS '同名人數'
FROM (
  SELECT *, COUNT(s_id) -1 AS num 
  FROM student
  GROUP BY s_name) a;

運行結果截圖:


2九、查詢1990年出生的學生名單

-- 2九、查詢1990年出生的學生名單
SELECT *
FROM student
WHERE YEAR(s_birth) = '1990';

運行結果截圖:


30、查詢平均成績大於等於85的全部學生的學號、姓名和平均成績

-- 30、查詢平均成績大於等於85的全部學生的學號、姓名和平均成績
SELECT st.`s_id` AS '學號',st.`s_name` AS '姓名',AVG(s_score) AS '平均成績'
FROM student st
INNER JOIN score sc 
ON st.`s_id`=sc.`s_id`
GROUP BY sc.`s_id`
HAVING AVG(s_score)>= 85;

運行結果截圖:


3一、查詢每門課程的平均成績,結果按平均成績升序排序,平均成績相同時,按課程號降序排列

-- 3一、查詢每門課程的平均成績,結果按平均成績升序排序,平均成績相同時,按課程號降序排列
SELECT c_id, AVG(s_score) AS '平均成績'
FROM score
GROUP BY c_id
ORDER BY AVG(s_score),c_id DESC;

運行結果截圖:


3二、查詢課程名稱爲"數學",且分數低於60的學生姓名和分數

-- 3二、查詢課程名稱爲"數學",且分數低於60的學生姓名和分數
SELECT st.`s_id`, st.`s_name`, s_score 
FROM student st
INNER JOIN score sc
ON st.`s_id`=sc.`s_id`
WHERE s_score < 60 AND sc.`c_id` IN (
SELECT c_id 
FROM course 
WHERE c_name = '數學');

運行結果截圖:


3三、查詢全部學生的課程及分數狀況

-- 3三、查詢全部學生的課程及分數狀況
SELECT sc.`s_id`,
SUM(CASE WHEN co.c_name = '語文' THEN sc.s_score ELSE NULL END) AS '語文成績',
SUM(CASE WHEN co.c_name = '數學' THEN sc.s_score ELSE NULL END) AS '數學成績',
SUM(CASE WHEN co.c_name = '英語' THEN sc.s_score ELSE NULL END) AS '英語成績'
FROM score sc INNER JOIN course co ON sc.`c_id`= co.`c_id`
GROUP BY sc.`s_id`;

運行結果截圖:


3四、查詢任何一門課程成績在70分以上的姓名、課程名稱和分數

-- 3四、查詢任何一門課程成績在70分以上的姓名、課程名稱和分數
SELECT st.`s_name` AS '姓名', co.`c_name` AS '課程名稱',sc.`s_score` AS '分數'
FROM student st
INNER JOIN score sc ON st.`s_id`= sc.`s_id`
INNER JOIN course co ON sc.`c_id`= co.`c_id`
WHERE sc.`s_score` >= 70;

運行結果截圖:


3五、查詢不及格的課程並按課程號從大到小排列

-- 3五、查詢不及格的課程並按課程號從大到小排列
SELECT co.`c_id`,co.`c_name`,sc.`s_score`
FROM course co
INNER JOIN score sc ON co.`c_id`=sc.`c_id`
WHERE s_score < 60
ORDER BY c_id DESC;

運行結果截圖:


3六、查詢課程編號爲03且課程成績在80分以上的學生的學號和姓名

-- 3六、查詢課程編號爲03且課程成績在80分以上的學生的學號和姓名
SELECT st.`s_id` AS '學號',st.`s_name` AS '姓名'
FROM student st
INNER JOIN score sc ON st.`s_id`= sc.`s_id` 
WHERE c_id = '03' AND s_score > 80;

運行結果截圖:


3七、求每門課程的學生人數

-- 3七、求每門課程的學生人數
SELECT c_id, COUNT(s_id) AS '選課人數'
FROM score
GROUP BY c_id;

運行結果截圖:


3八、成績不重複,查詢選修「張老師」老師所授課程的學生中成績最高的學生姓名及其成績

-- 3八、成績不重複,查詢選修「張老師」老師所授課程的學生中成績最高的學生姓名及其成績
SELECT st.`s_id` AS '學號' , st.`s_name` AS '姓名' ,MAX(sc.`s_score`) AS '成績' 
FROM student st
INNER JOIN score sc ON st.`s_id`= sc.`s_id`
WHERE sc.`c_id` IN (SELECT c_id
               FROM course
               WHERE t_id IN (SELECT t_id
                              FROM teacher 
                              WHERE t_name = '張老師'
                              ));

運行結果截圖:


3九、成績有重複的狀況下,查詢選修「張三」老師所授課程的學生中,成績最高的學生信息及其成績

-- 3九、成績有重複的狀況下,查詢選修「張老師」老師所授課程的學生中,成績最高的學生信息及其成績
SELECT * FROM
    (SELECT *, DENSE_RANK() over(ORDER BY s_score DESC) A
    FROM score
    WHERE c_id = (SELECT c_id FROM course WHERE t_id = (SELECT t_id FROM teacher WHERE t_name='張老師'))
) B
WHERE B.A=1;

運行結果截圖:


40、查詢不一樣課程成績相同的學生的學生編號、課程編號、學生成績

-- 40、查詢不一樣課程成績相同的學生的學生編號、課程編號、學生成績
SELECT a.`s_id`,a.`c_id`,b.`c_id`,a.`s_score`,b.`s_score`
FROM score a, score b
WHERE a.`s_id`= b.`s_id` AND a.`s_score`= b.`s_score` AND a.`c_id`<> b.`c_id`;

運行結果截圖:


4一、查詢每門功課成績最好的前兩名

-- 4一、查詢每門功課成績最好的前兩名
(SELECT * FROM score WHERE c_id = '01' ORDER BY s_score DESC LIMIT 2)
UNION 
(SELECT * FROM score WHERE c_id = '02' ORDER BY s_score DESC LIMIT 2)
UNION
(SELECT * FROM score WHERE c_id = '03' ORDER BY s_score DESC LIMIT 2);

運行結果截圖:


4二、統計每門課程的學生選修人數(超過5人的課程才統計)

要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列。

-- 4二、統計每門課程的學生選修人數(超過5人的課程才統計)。
-- 要求輸出課程號和選修人數,查詢結果按人數降序排列,若人數相同,按課程號升序排列
SELECT c_id,COUNT(s_id) AS '選修人數'
FROM score
GROUP BY c_id
HAVING COUNT(s_id) >= 5
ORDER BY COUNT(s_id) DESC, c_id;

運行結果截圖:


4三、檢索至少選修兩門課程的學生學號

-- 4三、檢索至少選修兩門課程的學生學號
SELECT s_id, COUNT(c_id) AS '選修課程數'
FROM score 
GROUP BY s_id
HAVING COUNT(c_id) >= 2;

運行結果截圖:


4四、查詢選修了所有課程的學生信息

-- 4四、查詢選修了所有課程的學生信息
SELECT * 
FROM student 
WHERE s_id IN (
  SELECT s_id
  FROM score
  GROUP BY s_id
  HAVING COUNT(c_id) = (SELECT COUNT(DISTINCT c_id) FROM course));

運行結果截圖:


4五、查詢各學生的年齡

-- 4五、查詢各學生的年齡
SELECT s_id,
       s_name,
       (YEAR(NOW()) - YEAR(s_birth)) AS '年齡'
FROM student;

運行結果截圖:


4六、按照出生日期來算,當前月日 < 出生年月的月日,則年齡減一

TIMESTAMPDIFF函數:有參數設置,能夠精確到年(YEAR)、天(DAY)、小時(HOUR),分鐘(MINUTE)和秒(SECOND),使用起來比datediff函數更加靈活。對於比較的兩個時間,時間小的放在前面,時間大的放在後面。

datediff函數:返回值是相差的天數,不能定位到小時、分鐘和秒。

-- 4六、按照出生日期來算,當前月日 < 出生年月的月日,則年齡減一
SELECT s_id,
       s_name,
       TIMESTAMPDIFF(YEAR,s_birth,NOW()) AS '年齡'
FROM student;

運行結果截圖:


4七、查詢本週過生日的學生

  • week(時間) 默認從0開始,並卻星期天默認爲第一天,國外的算法
  • week(時間,1) 從1開始,並卻星期一爲第一天,國內算法
-- 4七、查詢本週過生日的學生
SELECT *
FROM student
WHERE WEEK(s_birth) = WEEK(NOW());

-- 以週一爲一週的開始
SELECT *
FROM student
WHERE WEEK(s_birth) = WEEK(NOW(),1);

運行結果截圖:


4八、查詢下週過生日的學生

-- 4八、查詢下週過生日的學生
SELECT *
FROM student
WHERE WEEK(s_birth) = WEEK(NOW())+1;

-- 以週一爲一週的開始
SELECT *
FROM student
WHERE WEEK(s_birth) = WEEK(NOW(),1)+1;

運行結果截圖:


4九、查詢本月過生日的學生

-- 4九、查詢本月過生日的學生
SELECT *
FROM student
WHERE MONTH(s_birth) = MONTH(NOW());

運行結果截圖:


50、查詢下個月過生日的學生

--  50、查詢下個月過生日的學生
SELECT *
FROM student
WHERE MONTH(s_birth) = MONTH(NOW())+1;

運行結果截圖:


文章最後,給你們推薦一些受歡迎的技術博客連接

  1. JAVA相關的深度技術博客連接
  2. Flink 相關技術博客連接
  3. Spark 核心技術連接
  4. 設計模式 —— 深度技術博客連接
  5. 機器學習 —— 深度技術博客連接
  6. Hadoop相關技術博客連接
  7. 超全乾貨--Flink思惟導圖,花了3周左右編寫、校對
  8. 深刻JAVA 的JVM核心原理解決線上各類故障【附案例】
  9. 請談談你對volatile的理解?--最近小李子與面試官的一場「硬核較量」
  10. 聊聊RPC通訊,常常被問到的一道面試題。源碼+筆記,包懂
  11. 深刻聊聊Java 垃圾回收機制【附原理圖及調優方法】

歡迎掃描下方的二維碼或 搜索 公衆號「大數據高級架構師」,咱們會有更多、且及時的資料推送給您,歡迎多多交流!

                                           

       

相關文章
相關標籤/搜索