連接查詢
連接是關系型數據庫模型的主要特點。
連接查詢是關系型數據庫中最主要的查詢,主要包括內連接、外連接等通過聯結運算符可以實現多個表查詢。
在關系型數據庫管理系統中,表建立時各種數據之間的關系不必確定,常把一個實體的所有信息存放在一個表中,當查詢數據時通過連接操作查詢出存放在多個表中的不同實體信息,當兩個或多個表中存在相同意義的字段時,便可以通過這些字段對不同的表進行連接查詢。
本文將介紹多表之間的內連接查詢、外連接查詢。
創建測試數據
為了后面可以演示內連接、外連接中的左外連接和右外連接,下面創建一些測試數據,首先創建一張base_worker表,用於存放工人基本信息:
create table base_worker ( s_id int auto_increment, s_name varchar(20), s_age int, primary key(s_id) )engine=innodb, charset=utf8; insert into base_worker values(null, "aaa", 20); insert into base_worker values(null, "bbb", 21); insert into base_worker values(null, "ccc", 22); commit;
然后創建一張extra_worker表,用於存放工人額外信息:
create table extra_worker ( e_id int auto_increment, s_id int, s_nation varchar(20), s_phone varchar(30), primary key(e_id) )engine=innodb, charset=utf8; insert into extra_worker values(null, 1, "中國", "00000000"); insert into extra_worker values(null, 2, "美國", "11111111"); insert into extra_worker values(null, 5, "英國", "22222222"); commit;
兩張表之間通過s_id相關聯,當然這里沒有設置外鍵,因為我不太喜歡使用外鍵,一個是語法太麻煩了,另一個是外鍵的關聯關系太死了,外鍵不存在插入會報錯,還得重新定位問題。
內連接inner join
內連接(inner join)使用比較運算符進行表間某(些)列數據的比較操作,並列出這些表中與連接條件相匹配的數據行,組合成新的記錄。換句話說,在內連接查詢中,只有滿足條件的記錄才能出現在結果關系中。
對base_worker和extra_worker使用內連接:
select b.s_id, b.s_name, b.s_age, e.s_nation, e.s_phone from base_worker b, extra_worker e where b.s_id = e.s_id;
看一下查詢結果:
看到base_worker和extra_worker中分別有三條記錄,但是最終查詢出來只有兩條記錄,因為只有這兩條記錄可以通過s_id相匹配上。
另外一個細節點是,s_id這種在兩張表中都存在的字段,必須指明讀取的是哪張表中的s_id,否則SQL將報錯,但是s_name這種只在base_worker表中存在的字段則沒有這個限制。
最后,上面的SQL是內連接最常用的SQL寫法,內連接還有另外一種SQL寫法,結果也是一樣的:
select b.s_id, b.s_name, b.s_age, e.s_nation, e.s_phone from base_worker b inner join extra_worker e on b.s_id = e.s_id;
可以自己驗證一下,執行效率上也沒有什么差別。
左外連接left join
連接查詢將查詢多個表中相關聯的行,內連接時返回查詢結果集合中的僅僅是符合查詢條件和連接條件的行。但有時候需要包含沒有關聯的行中的數據,即返回查詢結果集合中的不僅僅包含符合的連接條件的行,而且還包含左表或右表中的所有數據行。外連接分為左外連接和右外連接,這里先看一下左外連接。
左外連接,返回的是左表中的所有記錄以及由表中連接字段相等的記錄。
看一下SQL:
select b.s_id, b.s_name, b.s_age, e.s_nation, e.s_phone from base_worker b left outer join extra_worker e on b.s_id = e.s_id;
看一下查詢結果:
顯示了三條紀錄,s_id為3的記錄在extra_worker表中並沒有s_nation與s_phone,所以這兩個值為null,但因為base_worker為左表,因此base_worker中的所有數據都會被查出來。
右外連接right join
右外連接是左外連接的反向連接,將返回右表中的所有行,如果右表中的某行在左表中沒有匹配的行,左表將返回空值。
看一下SQL:
select e.s_id, b.s_name, b.s_age, e.s_nation, e.s_phone from base_worker b right outer join extra_worker e on b.s_id = e.s_id;
注意一下,這里的s_id是extra_worker的而不是base_worker的。
看一下查詢結果:
同樣的,看到顯示了三條紀錄,s_id為5的記錄在base_worker中並沒有s_name與s_age,所以這兩個值為null,但因為extra_worker表為右表,因此extra_worker表中的所有數據都會被查出來。