一、多表連接類型
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
工作原理:
從左表讀出一條,選出所有與on匹配的右表紀錄(n條)進行連接,形成n條紀錄(包括重複的行,如:結果1和結果3),如果右邊沒有與on條件匹配的表,那連接的欄位都是null.然後繼續讀下一條。
引申:
我們可以用右表沒有on匹配則顯示null的規律, 來找出所有在左表,不在右表的紀錄, 注意用來判斷的那列必須聲明為not null的。
如:
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:
on a.c1 = b.c1 等同於using(c1)
2. INNER JOIN 和, (逗號) 在語意上是等同的
3. 當MySQL 在從一個表中檢索資訊時,你可以提示它選擇了哪一個索引。
如果 EXPLAIN 顯示 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. ONSELECT FROM LEFT JOIN USING ()
US表
例如: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
ID Name
1 Jimmy 4 Tom
表B:
ID Hobby
2 Basketball
2 Tennis4 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
顯示左表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種組合方式如果可以靈活使用,那麼簡單的語句結構也會確實如此簡單。