天天看點

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

建立進階聯結

上篇博文簡單的介紹了下聯結的使用,這篇博文就介紹下如何來建立進階聯結。

使用表别名

在前面的學習中,我們知道如何給列取一個别名,現在回顧下,如下:

select cust_name,upper(cust_name) as upper_name from customers;
           
《MySQL必知必會學習筆記》:進階聯結建立進階聯結

或者是,用concat函數來對客戶的姓名和電話進行組合為一個新的資訊 ,将這個新的資訊取一個别名,如下:

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

以上就是給列取别名,也可以給計算字段取别名。不僅如此,SQL還允許給表名取别名。這樣做有兩個主要理由,如下:

  • 縮短SQL語句
  • 允許在單條select語句中多次使用相同的表。

下面舉一個例子來說明,如何給表取别名。如下:

通過as為customers/orders/ordersitems 分别取别名為 c/o/items;這樣,在後面的列引用中,直接使用别名,而不是使用全名,這樣書寫起來稍微可以簡單一點點。

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

使用不同類型的聯結

上篇博文中,使用過内部聯結(即等值聯結)。先回顧下:内部聯結就是通過 table_name inner join InnerJoin_table_name on 子句來完成的;實際例子如下:

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

上面就是一個簡單的内部聯結,,由于剛好學習了給表取别名,就随帶把這個知識點也加進去了。

除了内部聯結之外,還有其他的3種形式,分别為:

  • 自聯結
  • 自然聯結
  • 外部聯結

下面一一進行介紹。

自聯結

自聯結,從字面意思就可以了解,就是隻存在一個表,自己和自己聯結。

下面看一個例子:想看下學生成績表中 數學分數為100的人的英語成績是多少分?

你可能會說,這個還需要用自聯結來完成吧,直接用where過濾就應該ok了吧。

的确,對于這個例子,确實可以直接用where子句來完成,如下:

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

除了可以采用上面的where過濾來完成,還可以采用子查詢來完成,如下:

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

除了采用上面介紹的兩種方法之外,還可以采用 自聯結來完成,如下:

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

這裡采用自聯結的方式來完成的,此查詢中的表實際上時相同的表,都是student2,由于我們需要對一個表引用兩次,是以就需要引入對表student2引入兩個不同的别名,否則對student2的引用就存在歧義。是以MySQL不知道你引用的是student2表中的哪個執行個體。

當引入别名後,所有的列的通路均需要用别名來指定,否則因為有歧義而報錯。

如下就是因為沒有指定是student2表中的哪個執行個體而報錯:

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

以上介紹了3中方法來完成這樣一個操作,在實際過程中,到底該用哪一種方法,我們應該都嘗試下,以确定哪一種的性能更好。

自然聯結

由于對多個表進行聯結的前提就是應該至少有一列出現在不止一個表中。标準的聯結(即内部聯結)會傳回所有資料(含有重複的列)。而自然聯結排除多次出現,使每個列隻傳回一次。

下面先看标準的聯結 ,當在聯結的過程中我們用(select *),則結果就是傳回所有的列資料。

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

而自然聯結是如何做到排除多次出現,使每個列隻傳回一次的呢??

答案是:系統不完成這項工作,由我們自己來完成它。自然聯結就是這樣一種聯結,其中我們隻能選擇那些唯一的列。這一般是通過對表使用通配符(select *),對所有其他表的列使用明确的子集來完成。

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

簡單來說:自然聯結就是我們指定輸出的内容,并不是輸出所有的内容(因為重複的列資料不是我們想得到的)。

外部聯結

明天繼續,太晚了,2016年4月3日01:45:33;

今天出去耍了一天,實在是太累,看部落格發現自己的這篇博文還沒有完成,于是在睡覺前花了點時間,看了下外部聯結,也實踐了下。

如下:

上面介紹了内聯結、自聯結、自然聯結這三種形式。下面就來介紹下外部聯結。什麼是外部聯結呢?

MySQL必知必會這本書上面是這樣說的:

許多聯結将一個表中的行與另一個表中的行相關聯。但有時候會需要包含沒有關聯行的那些行。例如:我們想看下所有客戶的訂單情況,包括那些至今尚未下訂單的客戶。

當遇到上面這種情況的時候,就需要外部聯結了。

為更好的實驗,我在customers表中插入了一個新的客戶資訊,此客戶資訊是沒有下任何訂單的。

如下:

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

如果我們不用外部聯結,先看下内部聯結的結果,看是否可以将哪些至今尚未下訂單的客戶顯示出來,如下:

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

從上面的結果可以看出,内部聯結是無法滿足我們這個要求的(即将所有客戶的訂單情況顯示出來,包括沒有下訂單的)

下面我們看下外部聯結,如下:

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

從結果可以看出,外部聯結将所有客戶的訂單情況進行了顯示,包括那些沒有下訂單的客戶。如果左表的某行在右表中沒有比對行,則在相關聯的結果集行中右表的所有選擇清單列均為空值。 這也是外部聯結和内部聯結的一個重要的不同的地方。

不知道到這裡,大家是否都了解了外部聯結。

簡單來說就是聯結包含了那些在相關表中沒有關聯行的行,這種類型的聯結就是外部聯結。

下面就将外部聯結的文法講解一下。

外部聯結包括:左外部聯結(left outer join)和右外部聯結(right outer join)。

左外部聯結就是:left 指出的是outer join左邊的表,即使用left outer join 從from子句的左邊表(上例中的customers表)中選擇所有行。

為了從右邊的表中選擇所有行,應該使用right outer join

《MySQL必知必會學習筆記》:進階聯結建立進階聯結

除了使用上面的right outer join 方式外,我們還可以在left outer join 方式的基礎上直接将兩個表的位置進行交換,也是可以達到同樣的效果。即左外部聯結可通過颠倒from或where子句中表的順序轉換為右外部聯結。

總結

關于聯結的使用,總結如下:

1)注意所使用的聯結類型,一般我們使用的是内部聯結,但外部聯結也是有效的。

2)保證使用正确的聯結條件,否則傳回不正确的結果

3)應該總是提供聯結條件,否則會得到笛卡爾積。

繼續閱讀