`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」表中「葉平老師」教的課的成績都更改成此課程的平均成績sql
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;
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 ( ) > ( );code
2: 獲取指定ID的學生的001課程的成績io
SELECT sc.
score
FROM score sc LEFT JOINcourse
co ON co.id
=sc.course_id
WHERE [指定ID] = sc.student_id
AND co.name
= '001';select3: 獲取指定ID的學生的002課程的成績方法
SELECT sc.
score
FROM score sc LEFT JOINcourse
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 JOINcourse
co ON co.id
=sc.course_id
WHERE st.id
= sc.student_id
AND co.name
= '001' ) > ( SELECT sc.score
FROM score sc LEFT JOINcourse
co ON co.id
=sc.course_id
WHERE st.id
= sc.student_id
AND co.name
= '002' );查詢
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
FROMscore
sc WHERE sc.score
> 60;2: 而後獲取剩餘的學生信息(經過NOT IN)
SELECT st.* FROM
student
st WHERE st.id
NOT IN ( SELECT sc.student_id
FROMscore
sc WHERE sc.score
> 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不使用
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
) FROMscore
sc WHERE sc.student_id
= [特定ID];3: 獲取總成績(每個同窗的)
SELECT SUM(sc.
score
) FROMscore
sc WHERE sc.student_id
= [特定ID];4: 組裝SQL
SELECT st.*,(SELECT COUNT( sc.
course_id
) FROMscore
sc WHERE sc.student_id
= st.id
) courseNum, (SELECT SUM(sc.score
) FROMscore
sc WHERE sc.student_id
= st.id
) scoreNum FROM student st;
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
FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
LEFT JOINteacher
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
FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
LEFT JOINteacher
te ON te.id
= co.teache_id
WHERE te.name
= '葉平老師' );
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 JOINcourse
co ON co.id
= sc.course_id
WHERE sc.student_id
= [特定ID] AND co.name
= '001';2: 統計某一學生是否學過 002 課程的信息
SELECT count(*) FROM
score
sc LEFT JOINcourse
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() FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
WHERE sc.student_id
= st.id
AND co.name
= '001') > 0 AND (SELECT count() FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
WHERE sc.student_id
= st.id
AND co.name
= '002') > 0;
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
FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
WHERE co.name
= '001';2: 獲取學過 001 課程的學生ID
SELECT sc.
student_id
FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
WHERE co.name
= '002'3: 獲取即學過 001 又學過 002 課程的學生ID
SELECT st1.student_id FROM ( SELECT sc.
student_id
FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
WHERE co.name
= '001' ) st1, ( SELECT sc.student_id
FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
WHERE co.name
= '002' ) st2 WHERE st1.student_id
= st2.student_id
;4:根據學生ID獲取學生信息(能夠有多種寫法)
-- IN 寫法:
SELECT * FROMstudent
st WHERE st.id
IN ( SELECT st1.student_id FROM ( SELECT sc.student_id
FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
WHERE co.name
= '001' ) st1,( SELECT sc.student_id
FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
WHERE co.name
= '002' )st2 WHERE st1.student_id
= st2.student_id
);
-- 把結果看成一個表、起別名再去查詢:
SELECT st.* FROMstudent
st,(SELECT st1.student_id FROM ( SELECT sc.student_id
FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
WHERE co.name
= '001' ) st1,( SELECT sc.student_id
FROMscore
sc LEFT JOINcourse
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
;
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(*) FROMcourse
);4:獲取學生的全部信息、組合sql 以下:
SELECT st.* FROM
student
st WHERE (SELECT count(* ) FROMscore
sc WHERE sc.student_id
= st.id
) < (SELECT count(*) FROMcourse
);
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
FROMstudent
st LEFT JOINscore
sc ON sc.student_id
= st.id
WHERE st.code
= '1001';2: 而後根據獲取的課程ID去查全部的學生信息、同時去重便可;
SELECT DISTINCT st.* FROM
student
st INNER JOINscore
sc ON sc.student_id
= st.id
WHERE sc.course_id
IN ( SELECT sc.course_id
FROMstudent
st LEFT JOINscore
sc ON sc.student_id
= st.id
WHERE st.code
= '1001' );
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
FROMstudent
st LEFT JOINscore
sc ON sc.student_id
= st.id
WHERE st.code
= '1001';2: 而後根據獲取到課程ID獲取學生ID;
SELECT DISTINCT sc.
student_id
FROMscore
sc WHERE sc.course_id
IN ( SELECT sc.course_id
FROMstudent
st LEFT JOINscore
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
FROMscore
sc WHERE sc.course_id
IN ( SELECT sc.course_id
FROMstudent
st LEFT JOINscore
sc ON sc.student_id
= st.id
WHERE st.code
= '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
FROMstudent
st LEFT JOINscore
sc ON sc.student_id
= st.id
WHERE st.code
= '1001';2: 獲取對應課程的全部學習同窗的ID、而且分組;
SELECT sc.
student_id
FROMscore
sc WHERE sc.course_id
IN ( SELECT sc.course_id
FROMstudent
st LEFT JOINscore
sc ON sc.student_id
= st.id
WHERE st.code
= '1001' ) GROUP BY sc.student_id
;到此爲止發現問題:只學了其中一門的也被查詢出來了、應該去掉.
3: 獲取學號爲 1001 的同窗所學課程數量
SELECT COUNT(*) FROM
student
st LEFT JOINscore
sc ON sc.student_id
= st.id
WHERE st.code
= '1001';4: 因此全部的符合條件的學生的ID集爲:
SELECT sc.
student_id
FROMscore
sc WHERE sc.course_id
IN ( SELECT sc.course_id
FROMstudent
st LEFT JOINscore
sc ON sc.student_id
= st.id
WHERE st.code
= '1001' ) GROUP BY sc.student_id
HAVING COUNT() = ( SELECT COUNT() FROMstudent
st LEFT JOINscore
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
FROMscore
sc WHERE sc.course_id
IN ( SELECT sc.course_id
FROMstudent
st LEFT JOINscore
sc ON sc.student_id
= st.id
WHERE st.code
= '1001' ) GROUP BY sc.student_id
HAVING COUNT() = ( SELECT COUNT() FROMstudent
st LEFT JOINscore
sc ON sc.student_id
= st.id
WHERE st.code
= '1001' ) );
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 JOINcourse
co ON co.id
= sc.course_id
LEFT JOINteacher
te ON te.id
= co.teache_id
WHERE te.name
= '葉平老師'3: 肯定要修改的值(獲取要修改的數據的平均值)
SELECT AVG(sc1.
score
) avgScore FROM (SELECT sc.* FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
LEFT JOINteacher
te ON te.id
= co.teache_id
WHERE te.name
= '葉平老師' ) sc14: 肯定修改的條件(獲取葉平老師所帶課程的ID)
SELECT co.* FROM
course
co LEFT JOINteacher
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.* FROMscore
sc LEFT JOINcourse
co ON co.id
= sc.course_id
LEFT JOINteacher
te ON te.id
= co.teache_id
WHERE te.name
= '葉平老師' ) sc1 ) WHERE sc.course_id
= ( SELECT co.id
FROMcourse
co LEFT JOINteacher
te ON te.id
= co.teache_id
WHERE te.name
= '葉平老師' );