MYSQL 面試中 查詢系列 常考問題


表結構:

`student`('id'、'name'、'code'、'age'、'sex')學生表
`teacher`('id'、'name')教師表
`course`('id'、'name'、'teacher_id')課程表
`score`('student_id'、'course_id'、'score')成績表

問題:

1: 查詢001課程比002課程成績高的所有學生的信息
2: 查詢所有課程成績小於60分的同學的信息名
3: 查詢平均成績大於60分的同學平均成績和學生的信息
4: 查詢所有同學的信息、選課數、總成績
5: 查詢沒學過 “葉平老師” 課的同學的信息
6: 查詢學過“001”並且也學過編號“002”課程的同學的信息
7: 查詢沒有學全所有課的同學的信息
8: 查詢至少有一門課與學號為“1001”的同學所學相同同學的信息
9: 查詢至少學過學號為1001的同學所有課程的 其他同學的信息
10: 把“score”表中“葉平老師”教的課的成績都更改為此課程的平均成績

解決:

創建表
CREATE TABLE `student` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  `code` varchar(15) DEFAULT NULL,
  `age` int(11) DEFAULT NULL,
  `sex` int(11) DEFAULT '1' COMMENT '1 男 2 女',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;


CREATE TABLE `teacher` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT '' COMMENT '老師名',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;


CREATE TABLE `course` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL COMMENT '課程名',
  `teache_id` int(11) DEFAULT NULL COMMENT '教師ID',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;


CREATE TABLE `score` (
  `student_id` int(11) DEFAULT NULL COMMENT '學生ID',
  `course_id` int(11) DEFAULT NULL COMMENT '課程ID',
  `score` int(11) DEFAULT NULL COMMENT '成績'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
問題1: 查詢001課程比002課程成績高的所有學生的信息;
SELECT st.* FROM student st WHERE ( SELECT sc.`score` FROM score sc LEFT JOIN `course` co ON co.`id`=sc.`course_id` WHERE st.`id` = sc.`student_id` AND co.`name` = '001' ) > ( SELECT sc.`score` FROM score sc LEFT JOIN `course` co ON co.`id`=sc.`course_id` WHERE st.`id` = sc.`student_id` AND co.`name` = '002' );

分解:

1: 按題意理解、寫的如下SQL

SELECT st.* FROM student st WHERE ( ) > ( );

2: 獲取指定ID的學生的001課程的成績

SELECT sc.score FROM score sc LEFT JOIN course co ON co.id=sc.course_id WHERE [指定ID] = sc.student_id AND co.name = '001';

3: 獲取指定ID的學生的002課程的成績

SELECT sc.score FROM score sc LEFT JOIN course co ON co.id=sc.course_id WHERE [指定ID] = sc.student_id AND co.name = '002';

4: 組裝SQL

SELECT st.* FROM student st WHERE ( SELECT sc.score FROM score sc LEFT JOIN course co ON co.id=sc.course_id WHERE st.id = sc.student_id AND co.name = '001' ) > ( SELECT sc.score FROM score sc LEFT JOIN course co ON co.id=sc.course_id WHERE st.id = sc.student_id AND co.name = '002' );

問題2: 查詢所有課程成績小於60分的同學的信息;
SELECT st.* FROM `student` st WHERE st.id NOT IN ( SELECT sc.`student_id` FROM `score` sc WHERE sc.`score` > 60 );

分解:

1: 先是獲取成績大於60的同學 (題意是所有成績都小於60的才符合、那么排除只要有一門成績大於60的即可)

SELECT sc.student_id FROM score sc WHERE sc.score > 60;

2: 然后獲取剩余的學生信息(通過NOT IN)

SELECT st.* FROM student st WHERE st.id NOT IN ( SELECT sc.student_id FROM score sc WHERE sc.score > 60 );

問題3: 查詢平均成績大於60分的同學的學號和平均成績和學生的信息;
SELECT st.*,AVG( sc.`score`) as AvgScore  FROM `score` sc LEFT JOIN student st ON st.`id` = sc.`student_id` GROUP BY sc.`student_id` HAVING AVG( sc.`score` ) > 60;

注意:

HAVING 應用與對 where 和 group by 查詢出來的分組進行過濾、查詢出滿足條件的分組結果。

1> having 只能應用與 group by(分組統計語句中)
2> where 是用於在初始表中篩選查詢,having用於在where和group by 結果分組中查詢
3> having 子句中的每一個元素也必須出現在select列表中
4> having語句可以使用聚合函數,而where不使用

問題4: 查詢所有同學的信息、選課數、總成績;
SELECT st.*,(SELECT COUNT( sc.`course_id`) FROM `score` sc WHERE sc.`student_id` = st.`id` ) courseNum, (SELECT SUM(sc.`score`) FROM `score` sc WHERE sc.`student_id` = st.`id`) scoreNum FROM student st;

分解:

1: 獲取所有同學的信息

SELECT st.* FROM student st;

2: 獲取選課數( 每一個同學都是一個特定的ID)

SELECT COUNT( sc.course_id) FROM score sc WHERE sc.student_id = [特定ID];

3: 獲取總成績(每一個同學的)

SELECT SUM(sc.score) FROM score sc WHERE sc.student_id = [特定ID];

4: 組裝SQL

SELECT st.*,(SELECT COUNT( sc.course_id) FROM score sc WHERE sc.student_id = st.id ) courseNum, (SELECT SUM(sc.score) FROM score sc WHERE sc.student_id = st.id) scoreNum FROM student st;

問題5: 查詢沒學過 “葉平老師” 課的同學信息
SELECT st.* FROM `student` st WHERE st.`id` NOT IN ( SELECT sc.`student_id` FROM `score` sc LEFT JOIN `course` co ON co.`id` = sc.`course_id` LEFT JOIN `teacher` te ON te.`id` = co.`teache_id` WHERE te.`name` = '葉平老師' );

分解:

1: 根據題意、取反、先獲取學過“葉平老師”課的同學

SELECT sc.student_id FROM score sc LEFT JOIN course co ON co.id = sc.course_id LEFT JOIN teacher te ON te.id = co.teache_id WHERE te.name = '葉平老師';

2: 然后在取反、獲取剩余的學生信息即可

SELECT st.* FROM student st WHERE st.id NOT IN ( SELECT sc.student_id FROM score sc LEFT JOIN course co ON co.id = sc.course_id LEFT JOIN teacher te ON te.id = co.teache_id WHERE te.name = '葉平老師' );

問題6: 查詢學過“001”也學過編號“002”課程的同學信息
解決方法1:
SELECT st.* FROM `student` st WHERE (SELECT count(*) FROM `score` sc LEFT JOIN `course` co ON co.`id` = sc.`course_id` WHERE sc.`student_id` = st.`id` AND co.`name` = '001') > 0 AND (SELECT count(*) FROM `score` sc LEFT JOIN `course` co ON co.`id` = sc.`course_id` WHERE sc.`student_id` = st.`id` AND co.`name` = '002') > 0;

分解:

1: 統計某一學生是否學過 001 課程的信息

SELECT count(*) FROM score sc LEFT JOIN course co ON co.id = sc.course_id WHERE sc.student_id = [特定ID] AND co.name = '001';

2: 統計某一學生是否學過 002 課程的信息

SELECT count(*) FROM score sc LEFT JOIN course co ON co.id = sc.course_id WHERE sc.student_id = [特定ID] AND co.name = '002';

3: 直接獲取 條件1 和 條件2 同時成立的數據

SELECT st.* FROM student st WHERE (SELECT count() FROM score sc LEFT JOIN course co ON co.id = sc.course_id WHERE sc.student_id = st.id AND co.name = '001') > 0 AND (SELECT count() FROM score sc LEFT JOIN course co ON co.id = sc.course_id WHERE sc.student_id = st.id AND co.name = '002') > 0;

解決方法2:
SELECT * FROM `student` st WHERE st.`id` IN ( SELECT st1.student_id FROM ( SELECT sc.`student_id` FROM `score` sc LEFT JOIN `course` co ON co.`id` = sc.`course_id` WHERE co.`name` = '001' ) st1,( SELECT sc.`student_id` FROM `score` sc LEFT JOIN `course` co ON co.`id` = sc.`course_id` WHERE co.`name` = '002' )st2 WHERE st1.`student_id` = st2.`student_id` );

或者

SELECT st.* FROM `student` st,(SELECT st1.student_id FROM ( SELECT sc.`student_id` FROM `score` sc LEFT JOIN `course` co ON co.`id` = sc.`course_id` WHERE co.`name` = '001' ) st1,( SELECT sc.`student_id` FROM `score` sc LEFT JOIN `course` co ON co.`id` = sc.`course_id` WHERE co.`name` = '002' )st2 WHERE st1.`student_id` = st2.`student_id`) st3 WHERE st3.`student_id`= st.`id`;

分解:

1: 獲取學過 001 課程的學生ID

SELECT sc.student_id FROM score sc LEFT JOIN course co ON co.id = sc.course_id WHERE co.name = '001';

2: 獲取學過 001 課程的學生ID

SELECT sc.student_id FROM score sc LEFT JOIN course co ON co.id = sc.course_id WHERE co.name = '002'

3: 獲取即學過 001 又學過 002 課程的學生ID

SELECT st1.student_id FROM ( SELECT sc.student_id FROM score sc LEFT JOIN course co ON co.id = sc.course_id WHERE co.name = '001' ) st1, ( SELECT sc.student_id FROM score sc LEFT JOIN course co ON co.id = sc.course_id WHERE co.name = '002' ) st2 WHERE st1.student_id = st2.student_id;

4:根據學生ID獲取學生信息(可以有多種寫法)

-- IN 寫法:
SELECT * FROM student st WHERE st.id IN ( SELECT st1.student_id FROM ( SELECT sc.student_id FROM score sc LEFT JOIN course co ON co.id = sc.course_id WHERE co.name = '001' ) st1,( SELECT sc.student_id FROM score sc LEFT JOIN course co ON co.id = sc.course_id WHERE co.name = '002' )st2 WHERE st1.student_id = st2.student_id );
-- 把結果當作一個表、起別名再去查詢:
SELECT st.* FROM student st,(SELECT st1.student_id FROM ( SELECT sc.student_id FROM score sc LEFT JOIN course co ON co.id = sc.course_id WHERE co.name = '001' ) st1,( SELECT sc.student_id FROM score sc LEFT JOIN course co ON co.id = sc.course_id WHERE co.name = '002' )st2 WHERE st1.student_id = st2.student_id) st3 WHERE st3.student_id= st.id;

問題7: 查詢沒有學全所有課的同學的信息
SELECT st.* FROM `student` st WHERE (SELECT count(*) FROM `score` sc WHERE sc.`student_id` = st.`id`) < (SELECT count(*) FROM `course`);

分解:

1: 獲取課的總數;

SELECT count(*) FROM course;

2: 獲取每個人的學習的課的總數;

SELECT count(*) FROM score sc WHERE sc.student_id = [特定ID];

3: 然后查詢的是 沒有學全所有課的學生、也就是學習的課數小於總課數

(SELECT count(* ) FROM score sc WHERE sc.student_id = [特定ID]) < (SELECT count(*) FROM course );

4:獲取學生的所有信息、組合sql 如下:

SELECT st.* FROM student st WHERE (SELECT count(* ) FROM score sc WHERE sc.student_id = st.id) < (SELECT count(*) FROM course);

問題8: 查詢至少有一門課與學號為1001的同學所學相同同學的信息
解決方法 1:
SELECT DISTINCT st.* FROM `student` st INNER JOIN `score` sc ON sc.`student_id` = st.`id` WHERE sc.`course_id` IN ( SELECT sc.`course_id` FROM `student` st LEFT JOIN `score` sc ON sc.`student_id` = st.`id` WHERE st.`code` = '1001' );

分解:

先獲取到學號為1001同學的所有學習課程、然后根據獲取的課程ID去查所有的學生信息、然后 DISTINCT 去重即可。

1: 先獲取到學號為1001同學的所有學習課程;

SELECT sc.course_id FROM student st LEFT JOIN score sc ON sc.student_id = st.id WHERE st.code = '1001';

2: 然后根據獲取的課程ID去查所有的學生信息、同時去重即可;

SELECT DISTINCT st.* FROM student st INNER JOIN score sc ON sc.student_id = st.id WHERE sc.course_id IN ( SELECT sc.course_id FROM student st LEFT JOIN score sc ON sc.student_id = st.id WHERE st.code = '1001' );

解決方法 2:
SELECT st.* FROM `student` st WHERE st.`id` IN (  SELECT DISTINCT sc.`student_id` FROM `score` sc WHERE sc.`course_id` IN ( SELECT sc.`course_id` FROM `student` st LEFT JOIN `score` sc ON sc.`student_id` = st.`id` WHERE st.`code` = '1001' ) );

分解:

先獲取學號為1001學生的課程、然后根據獲取到課程ID獲取學生ID、然后去重、然后獲取學生信息。(嵌套子查詢)

1: 先獲取到學號為1001同學的所有學習課程;

SELECT sc.course_id FROM student st LEFT JOIN score sc ON sc.student_id = st.id WHERE st.code = '1001';

2: 然后根據獲取到課程ID獲取學生ID;

SELECT DISTINCT sc.student_id FROM score sc WHERE sc.course_id IN ( SELECT sc.course_id FROM student st LEFT JOIN score sc ON sc.student_id = st.id WHERE st.code = '1001' );

3: 然后獲取學生信息

SELECT st.* FROM student st WHERE st.id IN ( SELECT DISTINCT sc.student_id FROM score sc WHERE sc.course_id IN ( SELECT sc.course_id FROM student st LEFT JOIN score sc ON sc.student_id = st.id WHERE st.code = '1001' ) );

問題9: 查詢至少學過學號為1001的同學所有課程的 其他同學的信息
SELECT st.* FROM `student` st WHERE st.`id` IN ( SELECT sc1.`student_id` FROM ( SELECT sc.* FROM `score` sc WHERE sc.`course_id` IN ( SELECT sc.`course_id` FROM `student` st LEFT JOIN `score` sc ON sc.`student_id` = st.`id` WHERE st.`code` = '1001' ) ) sc1 GROUP BY sc1.`student_id` HAVING COUNT(*) = ( SELECT COUNT(*) FROM `student` st LEFT JOIN `score` sc ON sc.`student_id` = st.`id` WHERE st.`code` = '1001' ) );

分解:

1: 獲取學號為 1001 的同學的所有課程ID;

SELECT sc.course_id FROM student st LEFT JOIN score sc ON sc.student_id = st.id WHERE st.code = '1001';

2: 獲取對應課程的所有學習同學的ID、並且分組;

SELECT sc.student_id FROM score sc WHERE sc.course_id IN ( SELECT sc.course_id FROM student st LEFT JOIN score sc ON sc.student_id = st.id WHERE st.code = '1001' ) GROUP BY sc.student_id;

到此為止發現問題:只學了其中一門的也被查詢出來了、應該去掉.

3: 獲取學號為 1001 的同學所學課程數量

SELECT COUNT(*) FROM student st LEFT JOIN score sc ON sc.student_id = st.id WHERE st.code = '1001';

4: 所以所有的符合條件的學生的ID集為:

SELECT sc.student_id FROM score sc WHERE sc.course_id IN ( SELECT sc.course_id FROM student st LEFT JOIN score sc ON sc.student_id = st.id WHERE st.code = '1001' ) GROUP BY sc.student_id HAVING COUNT() = ( SELECT COUNT() FROM student st LEFT JOIN score sc ON sc.student_id = st.id WHERE st.code = '1001' );

5: 組裝SQL、查詢學生信息。

SELECT st.* FROM student st WHERE st.id IN ( SELECT sc.student_id FROM score sc WHERE sc.course_id IN ( SELECT sc.course_id FROM student st LEFT JOIN score sc ON sc.student_id = st.id WHERE st.code = '1001' ) GROUP BY sc.student_id HAVING COUNT() = ( SELECT COUNT() FROM student st LEFT JOIN score sc ON sc.student_id = st.id WHERE st.code = '1001' ) );

問題10: 把“score”表中“葉平老師”教的課的成績都更改為此課程的平均成績
UPDATE `score` sc SET sc.`score` = ( SELECT AVG(sc1.`score`) avgScore FROM (SELECT sc.* FROM `score` sc LEFT JOIN `course` co ON co.`id` = sc.`course_id` LEFT JOIN `teacher` te ON te.`id` = co.`teache_id` WHERE te.`name` = '葉平老師' ) sc1 ) WHERE sc.`course_id` = ( SELECT co.`id` FROM `course` co LEFT JOIN `teacher` te ON te.`id` = co.`teache_id` WHERE te.`name` = '葉平老師' );

分解:

1: 理解為修改特定ID的數據

UPDATE score sc SET sc.score = () WHERE sc.course_id = ();

2: 要修改的數據( 獲取“score”表中“葉平老師”教的課的成績)

SELECT sc.* FROM score sc LEFT JOIN course co ON co.id = sc.course_id LEFT JOIN teacher te ON te.id = co.teache_id WHERE te.name = '葉平老師'

3: 確定要修改的值(獲取要修改的數據的平均值)

SELECT AVG(sc1.score) avgScore FROM (SELECT sc.* FROM score sc LEFT JOIN course co ON co.id = sc.course_id LEFT JOIN teacher te ON te.id = co.teache_id WHERE te.name = '葉平老師' ) sc1

4: 確定修改的條件(獲取葉平老師所帶課程的ID)

SELECT co.* FROM course co LEFT JOIN teacher te ON te.id = co.teache_id WHERE te.name = '葉平老師'

5: 組裝SQL即可

UPDATE score sc SET sc.score = ( SELECT AVG(sc1.score) avgScore FROM (SELECT sc.* FROM score sc LEFT JOIN course co ON co.id = sc.course_id LEFT JOIN teacher te ON te.id = co.teache_id WHERE te.name = '葉平老師' ) sc1 ) WHERE sc.course_id = ( SELECT co.id FROM course co LEFT JOIN teacher te ON te.id = co.teache_id WHERE te.name = '葉平老師' );


免責聲明!

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



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