- 多表查詢是對多張表的數據取笛卡爾積(關聯查詢可以對關聯表使用別名)
- 數據準備
insert into classes(name, `desc`) values
('計算機系2019級1班', '學習了計算機原理、C和Java語言、數據結構和算法'),
('中文系2019級3班','學習了中國傳統文學'),
('自動化2019級5班','學習了機械自動化');
insert into student(sn, name, qq_mail, classes_id) values
('09982','黑旋風李逵','xuanfeng@qq.com',1),
('00835','菩提老祖',null,1),
('00391','白素貞',null,1),
('00031','許仙','xuxian@qq.com',1),
('00054','不想畢業',null,1),
('51234','好好說話','say@qq.com',2),
('83223','tellme',null,2),
('09527','老外學中文','foreigner@qq.com',2);
insert into course(name) values
('Java'),('中國傳統文化'),('計算機原理'),('語文'),('高階數學'),('英文')
insert into score(score, student_id, course_id) values
-- 黑旋風李逵
(70.5, 1, 1),(98.5, 1, 3),(33, 1, 5),(98, 1, 6),
-- 菩提老祖
(60, 2, 1),(59.5, 2, 5),
-- 白素貞
(33, 3, 1),(68, 3, 3),(99, 3, 5),
-- 許仙
(67, 4, 1),(23, 4, 3),(56, 4, 5),(72, 4, 6),
-- 不想畢業
(81, 5, 1),(37, 5, 5),
-- 好好說話
(56, 6, 2),(43, 6, 4),(79, 6, 6),
-- tellme
(80, 7, 2),(92, 7, 6);
classes
student
course
score
- 內連接(表示兩個表都存在的結果)
select 字段 from 表1 別名1 [inner] join 表2 別名2 on 連接條件 and 其他條件;
select 字段 from 表1 別名1,表2 別名2 where 連接條件 and 其他條件;
案列:查詢每個同學姓名 課程名字 分數
//方法一
select student.name,course.name,score from student,course,score where student.id = score.student_id and score.course_id = course.id;
--方法二select student.name,course.name,score from student join score on student.id = score.student_id join course on score.course_id = course.id;
- 外連接
外連接分為左外連接和右外連接。如果聯合查詢,左側的表完全顯示我們就說是左外連接(如果這個記錄在右表中沒有匹配,就把對應的列填成NULL) ;右側的表完全顯示我們就說是右外連接。
-- 左外連接,表1完全顯示
select 字段名 from 表名1 left join 表名2 on 連接條件;
-- 右外連接,表2完全顯示
select 字段 from 表名1 right join 表名2 on 連接條件;
--案列
select * from score sco right join student stu on stu.id=sco.student_id;
- 自連接
自連接是指在同一張表連接自身進行查詢
select ... from 表1,表1 where 條件
select ... from 表1 join 表1 on 條件-案列
顯示所有“計算機原理”成績比“Java”成績高的成績信息
-起別名,因為兩個表的名字是一樣的
select * from score as s1,score as s2;
-篩選出java和計算機組成原理的分數
select * from score as s1,score as s2 where s1.student_id = s2.student_id and s1.course_id = 3 and s2.course_id =1;
-進行結果查詢select * from score as s1,score as s2 where s1.student_id = s2.student_id and s1.course_id = 3 and s2.course_id =1 and s1.score > s2.score;
-
子查詢(簡單sql拼成復雜sql)
-
子查詢是指嵌入在其他sql語句中的select語句,也叫嵌套查詢
-
單行子查詢:返回一行記錄的子查詢
查詢與“不想畢業” 同學的同班同學:
select * from student where classes_id=(select classes_id from student where
name='不想畢業');
- 多行子查詢:返回多行記錄的子查詢
查詢“語文”或“英文”課程的成績信息
-- 使用IN
select * from score where course_id in (select id from course where
name='語文' or name='英文');
-- 使用 NOT IN
select * from score where course_id not in (select id from course where
name!='語文' and name!='英文');可以使用多列包含:
-- 插入重復的分數:score, student_id, course_id列重復
insert into score(score, student_id, course_id) values
-- 黑旋風李逵
(70.5, 1, 1),(98.5, 1, 3),
-- 菩提老祖
(60, 2, 1);
-- 查詢重復的分數
SELECT*
FROMscore
WHERE( score, student_id, course_id ) IN ( SELECT score, student_id,
course_id FROM score GROUP BY score, student_id, course_id HAVING
count( 0 ) > 1 );[NOT] EXISTS關鍵字:-- 使用 EXISTS
select * from score sco where exists (select sco.id from course cou
where (name='語文' or name='英文') and cou.id = sco.course_id);
-- 使用 NOT EXISTS
select * from score sco where not exists (select sco.id from course cou
where (name!='語文' and name!='英文') and cou.id = sco.course_id);
- 在from子句中使用子查詢:子查詢語句出現在from子句中。這里要用到數據查詢的技巧,把一個子查詢當做一個臨時表使用。
查詢所有比“中文系2019級3班”平均分高的成績信息:
-- 獲取“中文系2019級3班”的平均分,將其看作臨時表
SELECTavg( sco.score ) score
FROMscore scoJOIN student stu ON sco.student_id = stu.idJOIN classes cls ON stu.classes_id = cls.id
WHEREcls.NAME = '中文系2019級3班';查詢成績表中,比以上臨時表平均分高的成績:SELECT*
FROMscore sco,(SELECTavg( sco.score ) score FROMscore scoJOIN student stu ON sco.student_id = stu.idJOIN classes cls ON stu.classes_id = cls.idWHEREcls.NAME = '中文系2019級3班') tmp
WHEREsco.score > tmp.score;
-
合并查詢
-
在實際應用中,為了合并多個select的執行結果,可以使用集合操作符 union,union all。使用UNION和UNION ALL時,前后查詢的結果集中,字段需要一致。
-
union
該操作符用于取得兩個結果集的并集。當使用該操作符時,會自動去掉結果集中的重復行。
案例:查詢id小于3,或者名字為“英文”的課程: select * from course where id<3 union select * from course where name='英文'; -- 或者使用or來實現 select * from course where id<3 or name='英文';
-
union all
-
該操作符用于取得兩個結果集的并集。當使用該操作符時,不會去掉結果集中的重復行
查詢id小于3,或者名字為“Java”的課程
-- 可以看到結果集中出現重復數據Java
select * from course where id<3
union all
select * from course where name='英文';