SQL聯結查詢(一)

Inner join和多表where查詢

正常查詢結果

1、inner join查詢

SELECT s.*,c.* FROM class c
INNER JOIN student s ON s.class_no=c.class_no

2、多表where查詢

SELECT s.*,c.* FROM class c,student s
WHERE s.class_no=c.class_no

上述兩條SQL的查詢結果一致,官方建議用join [ “ANSI SQL規範首選inner join 語法”],可以通過join知道多個關聯的關係,便於閱讀。
而‘多表where查詢’是inner join的簡寫方式。性能上也沒有差異(網上較多的說法,沒找到官方的解釋,有人做過測試,確實沒有太大差異)。

查詢結果爲 s中所有數據後面拼接上c表對應的數據。
這裏寫圖片描述

注意 不要忘了where子句
應該保證所有聯結都有where子句,否則DBMS將返回比想要的數據多得多的數據,同理,應該保證where子句的正確性。不正確的過濾條件將導致DBMS返回不正確的數據。
如果沒有where 語句

SELECT s.*,c.* FROM class c,student s 

將返回笛卡爾乘積值,即s表和c表中數據總數的乘積。
如:table1 : 【1,2,3】 table2:【4,5】 分別有3條和2條數據
將返回2*3=6條:14 ,15,24,25,34,35
而正確的應該返回3條

關聯字段重複時的結果

上面的例子講了一對一的情況,當出現一對多對多的情況時結果如下:
如果s/c表中有數據重複,會導致查詢結果中c/s表的
對應數據也成倍增加 ,即c中條件字段對應數據多出一條時,
結果中s對應的(每條符合條件的)數據也分別會多出一條

這裏寫圖片描述

由結果可知,聯結查詢以左邊的表爲主(from的表爲主,join的表爲輔 )。

關聯字段爲空時

當兩表對應的關聯字段在左邊的表中爲空時,查詢結果怎樣呢?
student表(將007的class_no改爲null):
這裏寫圖片描述

查詢結果:
這裏寫圖片描述
和前面的結果對比
這裏寫圖片描述
由對比可知,結果種去除了左表中關聯字段爲null的數據

同理,(將007的class_no改爲’xxx’,xxx爲student表中不存在的關聯字段值)當兩張表中關聯字段不同時,也不會顯示該行數據。

left join 和 right join

例1:查出所有學生及他們所在的班級信息

left join 和right join語法有點相似,只不過查詢的表之間關係正好相反,如下:

select s.*,c.* from db_student s
left join db_class c on c.cid=s.cid;

效果等同於:

select s.*,c.* from db_class c
right join db_student s on c.cid=s.cid;

這裏寫圖片描述
———————分割線———————–
這裏寫圖片描述
當學生沒有班級,或者學生的班級不存在時,班級對應信息爲空(null);

例2:查出所有班級及他們班所有學生信息

這個例子和例1有點相似,注意查詢目的和結果。

select c.*,s.* from db_class c 
left join db_student s on c.cid=s.cid;

效果等同於:

select c.*,s.* from db_student s
right join db_class c on c.cid=s.cid;

這裏寫圖片描述
———————分割線———————–
這裏寫圖片描述
同樣的,當班級沒有學生時,對應字段結果也未空(null);

總結

文字說明

inner join 會分別查出兩張表中關聯字段相同的所有結果,並進行乘積運算,當關聯字段爲空時,數據在結果中不顯示。

left join 和right join會查出主表中所有數據,並進行乘積運算,當關聯字段對應數據在從表中不存在時,從表對應列查詢結果爲空(null)

其中,對left join來說,select表爲主表,join表爲從表;
對right join來說join表爲主表,select 表爲從表;

根據查詢結果推測

以下內容均爲本人根據結果推測,便於對兩種join結果進行理解,不是dbms官方sql產品的實現邏輯。

sql的查詢邏輯大致爲:
1、 inner join :
查出a表中關聯字段不爲空的數據;
再查出b表中所有關聯字段不爲空的數據;
對a、b表數據行進行矩陣乘法(對比)運算,
當b表中關聯字段與a表中關聯字段相同時,兩條結果拼接爲一行數據,並保存該行數據,
當b表中關聯字段與a表中關聯字段不同時,丟棄該行b表數據,
當a表中所有數據都和b表數據比較完,也沒有在b表中找到對應的關聯結果時,丟棄掉(a表中)該部分數據

2、left join:
查出a表(主表)中所有數據,再將b表中所有行數據和a表數據進行對比,
當關聯字段相同時,將b表的該行數據 a表當前行數據拼接爲一條數據;
當b表中沒能找到和a表中數據關聯字段對應的行時,(a表中)數據保留,將b表對應字段置爲空null

full join

理解了left join後,再來看full join就會容易許多。
full join即‘全聯結’跟left join類似的是 full join不會以某張單獨表爲主而是以兩張表爲主,
即:a表中在b表不存在關聯字段對應的數據時將a表中數據列出,同時將b表部分置爲null;
同樣的當b表中對應的關聯字段在a表中沒有對應數據時,也將b表中該行數據保留,並將a表部分的數據置爲null;

full join的結果更像是
a left join b
union b left join a之後的值,即兩個left join 結果去重合並的結果。
文字描述起來可能比較難理解,可以參考w3c的樣例:
http://www.w3school.com.cn/sql/sql_join_full.asp

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章