子查詢與內連接查詢區別(效率上,連接查詢高於子查詢)、左連接以及連接的原理,還有內連接與左連接的區別
一、子查詢與內連接查詢區別(效率上,連接查詢高於子查詢)
❀①❀
子查詢:比起連接查詢慢點是:它取出表1 的第一行記錄 ,就去與表2 的每一行記錄進行比較,然后,它再取出表1 的第2行記錄,去與表2 的每一行記錄進行比較,又取出,然后與另外一個表的每一行記錄進行比較,又取出,又與每一行記錄比較,又取出。。。。。。
連接查詢:直接取出表1所有記錄與表2拼接到一起,然后在拼接后的同一張表再去比較,所以連接查詢效率快。
語法:子查詢:
select 列1,列2,(select 列3 from 表2 where 表1 與 表2 的共同屬性) from 表1;
語法:內連接:
語法: select 列1,列2,列3… from 表1,表2,表3 where 表之間的共同屬性。
或者:
select 列1,列2,列3… from (父表,(題意的主要數據來源))表1 inner join 表2 on (表1與表2 的共同屬性) 表1 inner join 表3 on (表1與表3 的共同屬性) 表2 inner join 表3 on (表2 與表3 的共同屬性);
-
子查詢的話,建議使用在查詢顯示出來的列只需要使用一張表的
-
內連接的話,建議使用查詢顯示出來的列需要使用到兩張表中的多個列 (多表查詢 適合用內連接
❀②❀(暫時不看,因為這里成里的條件,我還沒找到。。。。。)
打個比方:子查詢好比小呆呆,它喜歡隔壁的小芳,想把山上那棵有99朵玫瑰的玫瑰,全部送給小芳,但是呢小呆呆,就跑上山上摘了一朵玫瑰,問小芳這朵玫瑰,她喜歡不,喜歡小芳就收下,就這樣,小呆呆跑了99趟山上。小芳心里此刻就呵呵噠。。。
而連接查詢就好比小李子拿了一個大花籃,一下子就把長了99朵玫瑰的玫瑰花摘到花籃里,哼着小曲,送到小芳面前,問道:小芳,這99朵玫瑰里,你喜歡哪一朵就留下哪一朵。此刻小芳心里樂開花了。。。
❀③❀
內連接題目:
數據庫結構:(年級表、學科表、學生表、成績表)
#內連接,查詢學號(學生編號)、姓名、年級名稱、學科名稱、成績
where+and :
#內連接,查詢學號、姓名、年級名稱、學科名稱、成績 select stu.StuId,StuName,GradeName,SubjectName,Score from stu,grade,subject,score where stu.StuId = score.StuId and grade.GradeId=stu.GradeId and grade.GradeId=subject.GradeId and subject.SubjectId=score.SubjectId;
inner join:
select stu.StuId,StuName,GradeName,SubjectName,Score from score # from 關聯表1 inner join stu on stu.StuId=score.StuId #inner join 關聯表2 (找出關聯表2 與表1 的共同屬性) inner join grade on grade.GradeId=stu.GradeId #inner join 關聯表3 (找出關聯表3 與表1、表2 的共同屬性) inner join subject on subject.SubjectId=score.SubjectId and grade.GradeId=subject.GradeId; #inner join 關聯表4 (找出關聯表4 與表1、表2、表3 的共同屬性)
❀④❀
左連接:
(1)左表與右表
① 左表:記錄全部顯示出來
② 右表符合條件的記錄會顯示,左表多余部分(在右表中找不到符合條件對應的數據),則右表數據寫null.
(2)意義:對比兩個表的差異,查詢缺失信息—得到沒有
(3)語法:
select 列1,列2,列3 from 左表 left join 右表 on (右表與 左表 的共同屬性)
例如:#查詢缺考學生信息
把(查到的學生信息對應考試信息,出現null,當做一個臨時表)
#查詢缺考學生信息 select StuId,StuName from( #學生表與成績表的左連接,可以得到學生信息對應考試表,出現考試信息為null select stu.StuId,StuName,Score from stu left join score on stu.StuId=score.StuId) where score is null;
報錯:
報錯:Every derived table must have its own alias
翻譯報錯:每個派生表必須有自己的別名。
解決: 給臨時表(派生表)起個別名。
#查詢缺考學生信息 select StuId,StuName from( #學生表與成績表的左連接,可以得到學生信息對應考試表,出現考試信息為null select stu.StuId,StuName,Score from stu left join score on stu.StuId=score.StuId) as 考試信息 where score is null;
❀⑤❀
ps:兩張表的共同屬性關系是:1對多,不適合用內連接。
內連接需要一張表與另一張表的共同屬性是1對1,而不是1對多;(1:多只能選擇子查詢)。
舉例子:表結構如下:
題意:查詢顯示出結果如下:
分析:
內連接查詢:
因為參賽隊表中的 隊伍編號 同時被賽程表中的 主隊編號 和 客隊編號 引用作為外鍵,所以通過隊伍編號的把兩張表連接到一起,無法統一隊伍編號是要與主隊編號結合成一組還是和客隊編號結合成一組。(1對多 的外鍵引用關系不適合用內連接!)
-----------不過通過,給表起別名區分開(實現了一對一),也是可以使用內連接的。
1、子查詢:
#子連接
select (select TeamName from Team where `Match`.HostTeamId=Team.TeamId) as '主隊', MatchResult as '比分', (select TeamName from Team where `Match`.GustTeamId=Team.TeamId) as '客隊', from `Match`;
2、2-1 起別名實現1對1的內連接:
#內連接
select Team.TeamName as '主隊',MatchResult as '比分',t.TeamName as '客隊',MatchTime as '比賽時間' from Team, `Match`, Team as t where Team.TeamId=`Match`.HostTeamId and t.TeamId=`Match`.GustTeamId; # t 是Team 這張表起的一個別名,有“副表”的作用的意思
2-2 內連接寫法2:
#內連接寫法2
select Team.TeamName as '主隊',MatchResult as '比分',t.TeamName as '客隊',MatchTime as '比賽時間' from `Match` inner join Team on (Team.TeamId=`Match`.HostTeamId) inner join Team as t on (t.TeamId=`Match`.GustTeamId);
3、內連接跟子查詢結合起來使用
3-1.寫法一:
select Team.TeamName as '主隊',MatchResult as '比分', (select TeamName from Team where `Match`.GustTeamId=Team.TeamId) as '客隊',MatchTime as '比賽時間' from Team, `Match` where Team.TeamId=`Match`.HostTeamId;
3-2.寫法二:
#內連接inner join結合子查詢 select TeamName as '主隊',MatchResult as '比分',(select TeamName from Team where Team.TeamId=`Match`.GustTeamId),MatchTime as '比賽時間' from `Match` inner join Team on Team.TeamId=`Match`.HostTeamId;
❀⑥❀
二、左連接以及連接的原理
連接原理:
ps:所謂的內連接呀,左連接,右連接(連接)
例如 select 列1,列2,列3 from A 表
inner join B 表 on (B 表 與 A 表的共同屬性) #連接后變成AB表
inner join C 表 on (C 表 與 AB 表 的共同屬性) #連接后變成ABC 表
連接原理是 “A” 表 inner join “B” 表,即 “A” 表與 “B” 表連接成 “AB” 表,然后如果還 inner join C 的話,則是“AB” 表 與 “C” 表連接成 “ABC” 表。
❀⑦❀
三、內連接與左連接的區別:
1,內連接:
2,左連接:
對比看到,
內連接的拼接必須是你有,我有,才能拼接到一起。即把表A、表B共同部分拼接,而我有,你沒有,為了求同就把我的獨特給舍棄了。
左連接,是在連接的基礎上,實現了我有你沒有時,我顯示的時候,你用null對應。