SQL聯接查詢

2021-08-21 13:25:02 字數 2611 閱讀 2192

聯接查詢

join表操作符對兩個輸入表進行了操作。聯結有三種基本型別:交叉連線,內連線,外鏈結。這三種連線的區別是它們採用的邏輯查詢處理步驟各部相同,每種連線都有一套不同的步驟。交叉連線只有乙個步驟—笛卡爾積;內連線有兩個步驟—笛卡爾積,過濾;外鏈結有三個步驟—笛卡爾積,過濾,新增外部行。

交叉連線

交叉聯接是一種最簡單的聯接,交叉聯接只實現乙個笛卡爾積即可。這一步就是對兩張表進行操作,把它們聯接起來,生成兩者的笛卡爾積。也就是將乙個輸入表的每行和另一張表的每行進行匹配。如果一張表有n行,另一張表有m行,將得到m * n行。

ansi  sql-92:cross join

ansi  sql-89:在兩張表間放置乙個逗號

內連線

內連線要應用兩個邏輯查詢處理步驟:它首先像交叉聯接一樣,對兩個輸入表進行笛卡爾積運算:然後根據使用者指定的謂詞對結果進行過濾。和交叉聯接一樣,內聯接也有兩種標準語法。

ansi  sql-92:inner join 或者 join(由於內連線是預設的聯接方式,所以也可以只寫join)

ansi  sql-89:在兩張表間放置乙個逗號,在查詢的where子句中寫過濾條件。

強烈推薦使用inner join,因為假如你忘記寫過濾條件(on),執行時sql會報錯。而如果使用sql-89語法,則不會報錯。那麼這個內連線就變成交叉連線了! 而且實際開發中sql語句會非常的複雜,寫錯的概率就很大了。

組合連線

有時候過濾條件不止乙個,這時候就要用and來連線多個條件,這就叫做組合連線。例如:table2表中定義了乙個外來鍵(col1和col2),引用了table1表的col1和col2列,現在要寫乙個根據主外來鍵關係來連線兩個表的查詢語句。該條件如下:

from table1 as t1

join table2 as t2

on t1.col1 = t2.col1 and t1.col2 = t2.col2

不等連線

如果連線條件包含等號運算子,那麼這樣的連線叫做等值連線(equi join)。如果連線條件包含除等號以外的其他運算子,那麼這樣的連線叫做不等連線(non-equi join)。

多表連線

乙個聯接表運算子只對兩個表進行操作,而一條查詢語句可以包含多個聯接。通常,當from子句中包含多個表運算子時,表運算子在邏輯上是按從左到右的順序處理的。也就是說,第乙個表運算子的結果將作為第二個表運算子的輸入,第二個表運算子的結果將作為第三個運算子左邊的輸入,以此類推。

外連線

外連線會應用內連線所應用的兩個邏輯處理步驟(笛卡爾積和on過濾),此外還多乙個外連線特有的第三步:新增外部行。

在外聯接中,耍把乙個表標記為「保留的」表,可以在表名之間使用關鍵字left out join、right outer join ,以及 full outer join,其中 outer 失鍵字是可選的。 left關鍵字表示左邊表的行是保留的關鍵字表示右邊表的行是保留的,而full 關鍵字則表示左右兩邊表的行都是保留的。外聯接的第三個邏輯杏詢處理步驟就是要識別保留表中按照on條件在另乙個表找不到與之匹配的那些行,再把這些行新增到聯接 的前兩個步驟生成的結果表中:對於來自聯接的非保留表的那些列,追加的外部行中的 這些列則用null作為佔位符。

外連線常見問題

1.對外聯接中非保留表的列進行過濾

當檢查涉及外聯接的**時,查詢邏輯錯誤時,應該檢查的乙個地方就是where子句。如果where子句的條件是以《列》《運算子》《值》的形式引用了聯接中的非保留表的列。這通常就是存在錯誤的乙個標誌。因為外聯接得到的外部行中來自非保留字的列值均為null,而null 《運算子》《值》這種格式只會得到unknown(除非使用is null運算子,顯示查詢null值)。這種結果相當於抵消了外聯接的作用。

2.在多表連線中使用外連線

在from子句中執行的表運算子並不適用與「同時操作」,表運算子邏輯上是從左到右計算的。對外聯接的處理順序的調整,可能會影響到輸出結果,所以不能隨便改變它們的順序。

例如:假設現在要寫一條多表聯接查詢語句,先對兩張表進行外聯接,再和第三種表進行內連線。如果在內連線on子句中的條件是對來自外聯接非保留表的列和第三張表的列進行比較,那麼所有的外部行都會被過濾掉。

記住,對於外部行,其來自非保留表的列值為null;把null和任何值進行比較,得到的都是unknown;unknown都會被on過濾掉。

那麼我們如何避免這種情況呢?我們可以採用調換順序的方式來解決這個問題,或者採用()來讓內連線先執行,最後在外聯接。

2.隨外聯接一起使用count聚合函式

另乙個常見的邏輯錯誤是與外聯接一起使用count聚合函式有關。當對外連線的結果進行分組,再使用count(*)聚合函式時,聚合操作會把內部行和外部行都計算在內,因為它不計算行數,而不管行的內容。但通常是不希望把外部行也納入計數的考慮範圍之內。

為了解決這乙個問題,應該用count()來代替count(*),並從聯接的非保留表中選擇乙個列。這樣一來   count就會忽略外部行,因為這些行在計數列上的值為null。記住要選擇只有在外部行中列值為null的列。

SQL聯接查詢

舉例有兩表資訊如下 以上兩種查詢方式等價,如下圖所示內聯接inner join只取兩表存在關聯關係的資料 注 inner join與join相同,inner可省略不寫。查詢結果如下 如下圖所示,左聯接 左外聯接 左表 user表 資料將會完全展示,右表 dept表 只展示與左表存在關聯關係的資料。注...

sql基礎語法 聯接查詢

交叉聯接 1.不帶where條件的,將返回兩個表的 行乘積 select c.e.from sales.customers c cross join hr.employees e 2.帶where 條件的,交叉聯接不能使用on select e1.empid,e1.firstname,e1.last...

sql 左聯接,右聯接,內聯接的比較

首先需要解釋一下這幾個聯接的意思 2 left join 左聯接 返回包括左表中的所有記錄和右表中聯結字段相等的記錄。3 right join 右聯接 返回包括右表中的所有記錄和左表中聯結字段相等的記錄。inner join 等值連線 只返回兩個表中聯結字段相等的行。接下來,建立乙個資料庫,然後建立...