一:概念
關(guān)系數(shù)據(jù)庫可以在讀取表的時候?qū)Ρ磉M行聯(lián)接甫何。
聯(lián)接本質(zhì)上是以某種方式聯(lián)接兩個獨立的表出吹,并返回一張結(jié)果表。
二:join用法
tableA tableB
id name id name
-- ---- -- ----
1 Pirate 1 Rutabaga
2 Monkey 2 Pirate
3 Ninja 3 Darth Vader
4 Spaghetti 4 Ninja
-
Cross join 交叉聯(lián)接
交叉聯(lián)接通過from字句定義了一個在該字句中所列出關(guān)系上的笛卡爾積:
第一個關(guān)系中的每個元組與第二個關(guān)系中的所有元組都進行連接辙喂。select * from tablea捶牢,tableb; select * from tablea cross join tableb; id | name | id | name ----+-----------+----+---------- 1 | Pirate | 1 | Rutabaga 1 | Pirate | 2 | Pirate 1 | Pirate | 3 | Datch 1 | Pirate | 4 | Ninja 2 | Monkey | 1 | Rutabaga 2 | Monkey | 2 | Pirate 2 | Monkey | 3 | Datch 2 | Monkey | 4 | Ninja 3 | Ninja | 1 | Rutabaga 3 | Ninja | 2 | Pirate 3 | Ninja | 3 | Datch 3 | Ninja | 4 | Ninja 4 | Spaghetti | 1 | Rutabaga 4 | Spaghetti | 2 | Pirate 4 | Spaghetti | 3 | Datch 4 | Spaghetti | 4 | Ninja
-
(Inner可選)join 內(nèi)連接
tableA tableB tableC id name id name id words -- ---- -- ---- -- ---- 1 Pirate 1 Rutabaga 1 Rutabaga 2 Monkey 2 Pirate 2 Pirate 3 Ninja 3 Darth Vader 3 Darth Vader 4 Spaghetti 4 Ninja 4 Ninja
2.1 連接條件
natural join
自然連接運算作用于兩個關(guān)系,并產(chǎn)生一個關(guān)系作為結(jié)果巍耗。
不同于兩個關(guān)系上的笛卡爾積秋麸,它將第一個關(guān)系的每個元組與第二個關(guān)系的所有元組都進行連接;
自然連接只考慮那些在兩個關(guān)系模式中都出現(xiàn)的屬性上取值相同的元組對炬太。select * from tableA natural join tableC; id | name | words ----+-----------+---------- 1 | Pirate | Rutabaga 2 | Monkey | Pirate 3 | Ninja | Datch 4 | Spaghetti | Ninja (4 rows)
PS:
(1)結(jié)果中在兩個關(guān)系中都出現(xiàn)的屬性不會重復列出灸蟆,這樣的屬性只出現(xiàn)一次。
列出屬性的順序:先是兩個關(guān)系模式中都出現(xiàn)的屬性亲族,然后是只出現(xiàn)在第一個關(guān)系模式中的屬性炒考,最后是只出現(xiàn)在第二個關(guān)系模式中的屬性吓歇。
(2)自然連接的危險在于如果兩個關(guān)系模式中有多個同名屬性,需要全部匹配票腰。select * from tableA natural join tableB; id | name ----+------ (0 rows)
2.2 連接條件
join ... using(A1,A2,A3)
SQL提供了一種自然連接的構(gòu)造形式城看,這樣用戶來指定需要哪些列相等,而不需要同名屬性的取值全部相等杏慰。postgres=# select * from tableA join tableB using(id); id | name | name ----+-----------+---------- 1 | Pirate | Rutabaga 2 | Monkey | Pirate 3 | Ninja | Datch 4 | Spaghetti | Ninja (4 rows)
PS:
join ... using(A1,A2,A3)
需要給定一個屬性名列表测柠,其兩個輸入中都必須有指定名稱的屬性玖喘。
2.3 連接條件join ... on<predicate>
SQL支持另一種形式的連接條件:join ... on<predicate>
店煞,相比join ... using(A1,A2,A3)
可以指定任意的連接條件,更為靈活掉盅。select * from tableA join tableB on tableA.id=tableB.id; id | name | id | name ----+-----------+----+---------- 1 | Pirate | 1 | Rutabaga 2 | Monkey | 2 | Pirate 3 | Ninja | 3 | Datch 4 | Spaghetti | 4 | Ninja (4 rows) select * from tableA join tableB on tableA.id<tableB.id; id | name | id | name ----+--------+----+-------- 1 | Pirate | 2 | Pirate 1 | Pirate | 3 | Datch 1 | Pirate | 4 | Ninja 2 | Monkey | 3 | Datch 2 | Monkey | 4 | Ninja 3 | Ninja | 4 | Ninja (6 rows)
PS:
join ... on<predicate>
的結(jié)果中會重復出現(xiàn)兩個關(guān)系中相同的屬性朝扼。 -
outer join 外連接
在內(nèi)連接中赃阀,參與連接的任何一個關(guān)系或者兩個關(guān)系中的某些元組可能會丟失。
例如:同名屬性中擎颖,有一個關(guān)系的屬性值為null榛斯。
外連接運算與內(nèi)連接相似,但是會在結(jié)果中創(chuàng)建包含空值元組的方式搂捧,保留了那些在內(nèi)連接中丟失的元組驮俗。
外連接包含三種形式:- 左外連接
left outer join
,只保留出現(xiàn)在左邊的關(guān)系中的元組; - 右外連接
right outer join
允跑,只保留出現(xiàn)在右邊的關(guān)系中的元組王凑; - 全外連接
full outer join
,保留出現(xiàn)在兩個關(guān)系中的元組聋丝;
tableA tableB id name id name -- ---- -- ---- 1 Pirate 1 Rutabaga 3 null 2 null
select * from tableA left outer join tableB using(id); id | name | name ----+--------+---------- 1 | Pirate | Rutabaga 3 | | (2 rows) select * from tableA right outer join tableB using(id); id | name | name ----+--------+---------- 1 | Pirate | Rutabaga 2 | | (2 rows) select * from tableA full outer join tableB using(id); id | name | name ----+--------+---------- 1 | Pirate | Rutabaga 3 | | 2 | | (3 rows)
注意:
outer join 外連接
也可以像內(nèi)連接那樣與任意的連接條件(自然連接索烹、using條件或on條件)進行組合。 - 左外連接
三:總結(jié)
-
連接類型(內(nèi)/外連接)可以和連接條件自由組合弱睦。
-
注意不同數(shù)據(jù)庫的實現(xiàn)百姓。mysql
select * from a natural join b ; 相同屬性名,相同屬性值 select * from a cross JOIN b ; select * from a JOIN b ;select * from a FULL JOIN b ; 交叉連接效果 select * from a JOIN b + 連接條件on/using; select * from a LEFT/RIGHT JOIN b + 連接條件on/using;
-
[2016.10.12]