今天工做不忙,心血來潮找了幾個SQL語句練習題來作,一作才發現,基本功仍是不紮實.網上找的練習題只有答案,沒有解題思路,遂寫下這篇帖子,梳理解題流程, 請大牛多多指教.性能
表名和字段
–1.學生表
Student(s_id,s_name,s_birth,s_sex) --學生編號,學生姓名, 出生年月,學生性別
–2.課程表
Course(c_id,c_name,t_id) – --課程編號, 課程名稱, 教師編號
–3.教師表
Teacher(t_id,t_name) --教師編號,教師姓名
–4.成績表
Score(s_id,c_id,s_score) --學生編號,課程編號,分數測試
測試數據
--建表
--學生表
CREATE TABLE Student
(spa
`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
(.net
`c_id` VARCHAR(20), `c_name` VARCHAR(20) NOT NULL DEFAULT '', `t_id` VARCHAR(20) NOT NULL, PRIMARY KEY(`c_id`)
);
--教師表
CREATE TABLE Teacher
(code
`t_id` VARCHAR(20), `t_name` VARCHAR(20) NOT NULL DEFAULT '', PRIMARY KEY(`t_id`)
);
--成績表
CREATE TABLE Score
(blog
`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' , '王五');get
--成績表測試數據
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);
原文連接:https://blog.csdn.net/fashion...數學
題:一、查詢"01"課程比"02"課程成績高的學生的信息及課程分數
下面附上解題思路分析:it
那位大牛寫的標準答案:
select a.* ,b.s_score as 01_score,c.s_score as 02_score from
student a
join score b on a.s_id=b.s_id and b.c_id='01'
left join score c on a.s_id=c.s_id and
c.c_id='02' or c.c_id = NULL where b.s_score>c.s_score
拆解:
(1)先查出全部學生的課程1的分數及該學生信息
select a.* ,b.s_score as 01_score from student a join score b on a.s_id=b.s_id and b.c_id='01'
(2) 再用左外聯接查出這些學生課程2的分數,由於吳蘭02課程沒有考,因此空.
select a.* ,b.s_score as 01_score,c.s_score as 02_score from
student a
join score b on a.s_id=b.s_id and b.c_id='01'
left join score c on a.s_id=c.s_id and c.c_id='02'
上邊的第二個鏈接不能用內鏈接,由於內鏈接只顯示雙方條件都符合的,即兩個課程都參加考試了的,因此就不會顯示吳蘭的信息了.
請注意,上邊的left join的主體是第一次join以後的臨時表,而不是原student表,每一個join或者left join的主體都是前面的臨時表,除非只有一個join..
(3)、最後一步,在最後加上where條件 b.s_score > c.s_score ,即課程1分數 > 課程2分數
注: 在使用left join時,on and和on where條件的區別以下:
I、on條件是在生成臨時表時使用的條件,它無論on中的條件是否爲真,都會返回左邊表中的記錄。
II、where條件是在臨時表生成好後,再對臨時表進行過濾的條件。這時已經沒有left join的含義(必須返回左邊表的記錄)了,條件不爲真的就所有過濾掉,on後的條件用來生成左右表關聯的臨時表,where後的條件對臨時表中的記錄進行過濾。是最後一步總篩選.
III、where中不能用別名01_score,02_score,不然會提示沒有此字段,這是基本常識,不過仍是要提醒一下,共勉.
標準答案里加了個or c.c_id = NULL 這個加不加都行,由於這裏是比較課程1課程2的,
且前面有and c.c_id='02'了,這一步不會執行(由於會短路求值)若是c_id爲NULL,那全部的課程2分數都爲NULL, 就沒有比較的意義了.
第二種解法是這樣:
select a.*,b.s_score as 01_score,c.s_score as 02_score from student a,score b,score c
where a.s_id=b.s_id
and a.s_id=c.s_id
and b.c_id='01'
and c.c_id='02'
and b.s_score>c.s_score
此寫法比較好理解,雖然不夠優雅,可是性能好.第一種寫法的聯查很費性能,在開發中能不用就不用.