本文最新發(fā)布于http://www.lovestblog.cn,歡迎轉載該文,但請注明文章出處,謝謝合作。
mysql的from從句用來指定參與查詢的表,當然也可以是生成的中間表,在表前我們有時需要指定數(shù)據(jù)庫,這主要是用在我們需要訪問當前數(shù)據(jù)庫之外的數(shù)據(jù)庫中的表的情況,在這中情況下我們采用"."操作符來進行,如userdb.user,其實userdb為數(shù)據(jù)庫名,user為表名,這是對mysql數(shù)據(jù)庫而言的,對于DB2和Oracle就不是通過指定數(shù)據(jù)庫名了,而是指定sql用戶了,這就是說不同sql用戶可以建立相同名字的表,但是同一個sql用戶只能建立唯一名字的表。這就是它們在這表規(guī)范上面的區(qū)別。對于列規(guī)范,mysql可以在需要查詢的列則可以采用如下形式進行訪問:“數(shù)據(jù)庫名.表名.列名”。對于多個表的規(guī)范,也就是涉及查詢多個表的情況下,執(zhí)行的過程是采用笛卡爾積的形式進行的。也就是說生成的中間表的列數(shù)為兩個表中列數(shù)的總和,而行的總數(shù)等于一個表中的行的數(shù)量與另外一個表中行的數(shù)量的乘積。
對于from從句中使用假名的情況,比如select u.id,name,age,a.account from utb as u,atb as a where u.id=a.user_id,在我們使用假名之后,那么在該sql語句的任何地方都只能使用假名,不能使用真實的表名,同時上面的as關鍵字也是可以省略的,也就是說對于上面的語句不能用atb來取代a,utb來取代u了。雖然from從句不是我們指定的第一條語句,但是絕對是第一個被處理的語句,所以在聲明假名前使用假名不會導致錯誤。如果一條from從句引用到兩個有著相同名稱的表,則必須使用假名。如:

2

3

對于多個表間的連接處理可能會導致有相同的結果,即有重復的結果,sql并不會自動從最終結果中刪除重復的行,這是如果我們不希望在結果中出現(xiàn)重復的行,那么我們可以在select后直接指定distinct。如:

2

3

接下來說說連接哈,對于內連接,如果是兩個表的話,就取兩個表的一個交集,如果是左外連接的話,那就是左邊的表全取,右邊沒有的用null替代,弱國是右外連接的話,那就是右邊的表全取,左邊沒有的用null表示。下面看看一個具體的例子:

2

3

4

5

6

內連接 (顯示兩表id匹配的)

2

3

4

左連接(顯示join 左邊的表的所有數(shù)據(jù),exam只有兩條記錄,所以stu.id,grade 都用NULL 顯示)

2

3

4

5

右連接(與作連接相反,顯示join右邊表的所有數(shù)據(jù))

2

3

4

內連接取交集,外連接分左和右,
左連接左邊的全取,
右連接右邊的全取
對于連接的列的名稱相同的話,那么可以使用using來替代條件,如上面的內連接可以這樣改寫:

對于左外連接使用的情況一般是當左表的連接列中存在未出現(xiàn)在右表的連接列中的值時,左外連接才有用。
還有個全外連接的,也就是說只要在兩個表中出現(xiàn)的記錄都會在中間表中出現(xiàn),當右表有而左表沒有或當左表有而右表沒有的時候用null表示。具體語法如下:select stu.id,exam.id,stu.name, exam.grade from stu full join exam using(id)。
交叉連接:就是顯示求表的笛卡爾積,select * from teams cross join penalties.這句完全等價于select teams.*,penalties.* from teams,penalties.
聯(lián)合連接:select * from teams union join penalties,這個其實很容易理解,產生結果所包含的列為兩個表所有的列和,對于數(shù)據(jù)的列出,首先列出左表的數(shù)據(jù),對于屬于右表的列,用null表示,接下來列出右表的數(shù)據(jù),對于屬于左表的列用null表示。
自然連接:select * from teams nature inner join penalties where division='first';此句完全等同與select t.playerno,t.teamno,t.division,pen.paymentno,pen.payment_date,pen.amount from teams as t inner join penalties as pen on t.playerno=pen.playerno where dividion='first'.相比就知道,我們無須顯示指出必須要連接到哪些列,sql會自動查找兩表中是否有相同名稱的列,且假設他們必須在連接條件中使用。此處的on或using從句是多余的,因此不允許使用。
下面看個例子創(chuàng)建一個稱為towns的虛擬表:

2

3

4

5

6

7

8

9

結果為:

2

3

4

5

6
