首頁  >  文章  >  資料庫  >  MySQL多表聯合查詢說明

MySQL多表聯合查詢說明

伊谢尔伦
伊谢尔伦原創
2017-01-16 16:56:571622瀏覽

一、多表連接類型
1. 笛卡爾積(交叉連接) 在MySQL中可以為CROSS JOIN或者省略CROSS即JOIN,或者使用','  如:

        由於其返回的結果為被連接的兩個資料表的乘積,因此當有WHERE, ON或USING條件的時候一般不建議使用,因為當資料表項目太多的時候,會非常慢。一般使用LEFT [OUTER] JOIN或RIGHT [OUTER] JOIN

 2.   內連接INNER JOIN 在MySQL中把INNER JOIN叫做等值連接,即需要指定等值連接條件在MySQL中CROSS和INNER JOIN被分割在一起。 join_table: table_reference [INNER | CROSS] JOIN table_factor [join_condition]

SELECT * FROM table1 CROSS JOIN table2 
SELECT * FROM table1 JOIN table2 
SELECT * FROM table1,table2

3. MySQL中的外連接,分為左外連接和右連接,即除了返回符合連接條件的結果之外,還要返回左表(左連接)或右表(右連接)中不符合連接條件的結果,相對應的使用NULL對應。

範例:

user表:

id | name
———
1 | libk
2 | zyfon
3 | daodao

user_action表:

user_id | action
—————
1 | jump
1 | kick
1 | jump
2 | run
4 | swim

sql:

select id, name, action from user as u
left join user_action a on u.id = a.user_id

resd:

id | name  | action
——————————–
1 | libk     | jump      ①
1 | libk     | kick       ②
1 | libk     | jump      ③
2 | zyfon   | run        ④
3 | daodao | null       ⑤

sql:

select id, name, action from user as u
left join user_action a on u.id = a.user_id
where a.user_id is NULL

紀錄,但是沒有在結果中出現,
而user表中的id=3, name=daodao的用戶在user_action中沒有相應的紀錄,但是卻出現在了結果集中
因為現在是left join,所有的工作以left為準.

結果1,2,3,4都是既在左表又在右表的紀錄,5是只在左表,不在右表的紀錄

 工作原理:

從左表讀出一條,選出所有與on匹配的右表紀錄(n條)進行連接,形成n條紀錄(包括重複的行,如:結果1和結果3),如果右邊沒有與on條件匹配的表,那連接的欄位都是null.然後繼續讀下一條。


引申:
我們可以用右表沒有on匹配則顯示null的規律, 來找出所有在左表,不在右表的紀錄, 注意用來判斷的那列必須聲明為not null的。
如:

sql:

id | name | action
————————–
3 | daodao | NULL
 
——————————————————————————–
 (注意:


        1.欄位值為null    

上面sql的result:

mysql> SELECT * FROM table1 USE INDEX (key1,key2)
-> WHERE key1=1 AND key2=2 AND key3=3;
mysql> SELECT * FROM table1 IGNORE INDEX (key3)
-> WHERE key1=1 AND key2=2 AND key3=3;

一般用法:

a. LEFT [OUTER] JOIN:

除了傳回符合連接條件的結果之外,還需要顯示左表中不符合連接條件的資料列,相對應使用NULL對應

SELECT column_name FROM table1 LEFT [OUTER] JOIN table2 ON table1.column=table2.column  
b. RIGHT [OUTER] JOIN:

RIGHT的結果之外,還需要顯示右表中不符合連線條件的資料列,對應使用NULL對應

SELECT column_name FROM table1 RIGHT [OUTER] JOIN table2 ON table1.column=table2.column  
Tips:

Tips:



on a.c1 = b.c1 等同於using(c1)
2. INNER JOIN 和, (逗號) 在語意上是等同的
3. 當MySQL 在從一個表中檢索資訊時,你可以提示它選擇了哪一個索引。
如果 EXPLAIN 顯示 MySQL 使用了可能的索引清單中錯誤的索引,這個特性將是很有用的。

透過指定 USE INDEX (key_list),你可以告訴 MySQL 使用可能的索引中最適合的一個索引在表中尋找記錄行。

可選的二選一句法 IGNORE INDEX (key_list) 可用來告訴 MySQL 不使用特定的索引。如:

mysql>
SELECT * FROM table1,table2 WHERE table1.id=table2.id;

二、表格連接的限制條件

 新增顯示條件WHERE, ON, USING

1. WHERE子句

mysql>
SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id;
SELECT * FROM table1 LEFT JOIN table2 ON table1.id=table2.id
LEFT JOIN table3 ON table2.id=table3.id;

2. ON

SELECT FROM LEFT JOIN USING ()
US表

3. USING,如果連接的兩個子句表連接條件的兩個欄位有相同的名字的話可以使用USING

 例如:

mysql>
 
SELECT artists.Artist, cds.title, genres.genre 
  
FROM cds 
  
LEFT JOIN genres N cds.genreID = genres.genreID 
  
LEFT JOIN artists ON cds.artistID = artists.artistID;

連接多於兩個表的情況舉例:

mysql>
 
SELECT artists.Artist, cds.title, genres.genre 
  
FROM cds 
  
LEFT JOIN genres ON cds.genreID = genres.genreID 
  
 LEFT JOIN artists -> ON cds.artistID = artists.artistID
  
 WHERE (genres.genre = 'Pop');

Select A.Name, B.Hobby from A, B where A.id = B.id

reee

等到多表查詢的時候,需要根據查詢的情況,想好使用哪種連接方式效率更高。

 1. 交叉連接(笛卡爾積)或內連接[INNER | CROSS] JOIN

 2. 左外連接LEFT [OUTER] JOIN或右外連接RIGHT [OUTER] JOIN 注意指定連接條件WHERE, ON,USING .

PS:基本的JOIN用法

首先我們假設有2個表格A和B,他們的表格結構和欄位分別為:


表A:

ID Name
1 Tim

2 Jimmy


ID Name
1 Jimmy 4 Tom

表B:
ID Hobby

1 Football

2 Basketball

2 Tennis

4 Soccer1.  內聯結:

Name Hobby
Tim Football
Jimmy Basketball
Jimmy Tennis
Tom Soccer

 這是隱式的內聯結,查詢的結果是:

Select A.Name from A INNER JOIN B ON A.id = B.id
🎜🎜它的作用和🎜🎜
Select A.Name from A INNER JOIN B ON A.id = B.id

是一样的。这里的INNER JOIN换成CROSS JOIN也是可以的。

2.  外左联结

Select A.Name from A Left JOIN B ON A.id = B.id

 典型的外左联结,这样查询得到的结果将会是保留所有A表中联结字段的记录,若无与其相对应的B表中的字段记录则留空,结果如下:

Name Hobby
Tim Football
Jimmy Basketball,Tennis
John
Tom Soccer

所以从上面结果看出,因为A表中的John记录的ID没有在B表中有对应ID,因此为空,但Name栏仍有John记录。
3.  外右联结
如果把上面查询改成外右联结:

Select A.Name from A Right JOIN B ON A.id = B.id

则结果将会是:

Name Hobby
Tim Football
Jimmy Basketball
Jimmy Tennis
Tom Soccer

这样的结果都是我们可以从外左联结的结果中猜到的了。

说到这里大家是否对联结查询了解多了?这个原本看来高深的概念一下子就理解了,恍然大悟了吧(呵呵,开玩笑了)?最后给大家讲讲MySQL联结查询中的某些参数的作用:
1.USING (column_list):其作用是为了方便书写联结的多对应关系,大部分情况下USING语句可以用ON语句来代替,如下面例子:

a LEFT JOIN b USING (c1,c2,c3)

其作用相当于下面语句

a LEFT JOIN b ON a.c1=b.c1 AND a.c2=b.c2 AND a.c3=b.c3

只是用ON来代替会书写比较麻烦而已。

2.NATURAL [LEFT] JOIN:这个句子的作用相当于INNER JOIN,或者是在USING子句中包含了联结的表中所有字段的Left JOIN(左联结)。

3.STRAIGHT_JOIN:由于默认情况下MySQL在进行表的联结的时候会先读入左表,当使用了这个参数后MySQL将会先读入右表,这是个MySQL的内置优化参数,大家应该在特定情况下使用,譬如已经确认右表中的记录数量少,在筛选后能大大提高查询速度。

最后要说的就是,在MySQL5.0以后,运算顺序得到了重视,所以对多表的联结查询可能会错误以子联结查询的方式进行。譬如你需要进行多表联结,因此你输入了下面的联结查询:

SELECT t1.id,t2.id,t3.id
FROM t1,t2
LEFT JOIN t3 ON (t3.id=t1.id)
WHERE t1.id=t2.id;

但是MySQL并不是这样执行的,其后台的真正执行方式是下面的语句:

SELECT t1.id,t2.id,t3.id
FROM t1,( t2 LEFT JOIN t3 ON (t3.id=t1.id) )
WHERE t1.id=t2.id;

这并不是我们想要的效果,所以我们需要这样输入:

SELECT t1.id,t2.id,t3.id
FROM (t1,t2)
LEFT JOIN t3 ON (t3.id=t1.id)
WHERE t1.id=t2.id;

MySQL联合查询效率较高,以下例子来说明联合查询(内联、左联、右联、全联)的好处:

T1表结构(用户名,密码)   
userid(int)   usernamevarchar(20)   passwordvarchar(20)   
1   jack  jackpwd   
2   owen  owenpwd   


T2表结构(用户名,密码)   
userid(int)   jifenvarchar(20)   dengjivarchar(20)   
    1   20   3   
    3   50   6   


第一:内联(inner join)
如果想把用户信息、积分、等级都列出来,那么一般会这样写:

select * from T1, T3 where T1.userid = T3.userid
(其实这样的结果等同于select * from T1 inner join T3 on T1.userid=T3.userid )。

把两个表中都存在userid的行拼成一行(即内联),但后者的效率会比前者高很多,建议用后者(内联)的写法。

SQL语句:
select * from T1 inner join T2 on T1.userid = T2.userid

运行结果   
T1.userid   username   password   T2.userid   jifen   dengji   
1   jack   jackpwd   1   20   3   

第二:左联(left outer join)
显示左表T1中的所有行,并把右表T2中符合条件加到左表T1中;
右表T2中不符合条件,就不用加入结果表中,并且NULL表示。

SQL语句:
select * from T1 left outer join T2 on T1.userid = T2.userid

运行结果   
T1.userid   username   password   T2.userid   jifen   dengji   
1   jack   jackpwd   1   20   3   
2   owen   owenpwd   NULL   NULL   NULL   

第三:右联(right outer join)。

顯示右表T2中的所有行,並將左表T1中符合條件加到右表T2中;
左表T1中不符合條件,就不用加入結果表中,且NULL表示。

SQL語句:
select * from T1 right outer join T2 on T1.userid = T2.userid

運算jack   jackpwd   1   20   3   
NULL   NULL   NULL 3   50   6   



第四:全聯(full outer join)


顯示左表T1、右表T2兩邊中的所有行,即右聯表

顯示左表T1、右表T2兩邊中的所有行,即右聯表組合在一起,然後過濾掉重複的。


SQL語句:

select * from T1 full outer join T2 on T1.userid = T2.userid 
運算  jack   jackpwd   1   20   3   
2   owen   owenpwd NULL   NULL   NULL   
NULL   NULL   NULL   3   50   6   

總結,關於共同詢問,效率的確實比較高,4種組合方式如果可以靈活使用,那麼簡單的語句結構也會確實如此簡單。




陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
上一篇:MySQL基本指令下一篇:MySQL基本指令