1.連接查詢
如:SELECT * FROM t1, t2;
上述FROM語句將t1表,t2表連接。
假設t1表含n條記錄,t2表含m條記錄,則t1, t2得到的表將包含n*m條記錄。
我們以一個混合連接,過濾的查詢分析語句執行過程。
如:SELECT * FROM t1, t2 WHERE t1.m1 > 1 AND t1.m1 = t2.m2 AND t2.n2 < ‘d’;
(1).針對FROM子句得到結果集1。
(2).對結果集1中每行執行過濾條件,得到結果集2。
(3).對結果集2執行SELECT得到最終結果集。
上述是從執行效果角度解釋執行邏輯。實際執行中為了效率優化的考量,會視t1為驅動表,視t2為被驅動表。
先結合WHERE子句對驅動表執行過濾,再針對過濾后表中每條記錄與被驅動表結合執行其他過濾條件以得到最終結果集。
2.內連接和外連接
執行連接查詢時,如果驅動表中某一行執行連接后得到的多行中,全部被WHERE過濾掉了,這樣最終結果集中將不含驅動表此行的相關信息,有時這不是我們希望的。故,引入內連接,外連接。
(1).對內連接,如驅動表的記錄在被驅動表找不到匹配的記錄,則最終結果集中將不含驅動表此行的相關信息。這就是默認下的表現。
(2).對外連接,如驅動表的記錄在被驅動表找不到匹配的記錄,則最終結果集中將依然包含一條此驅動表此行的對應行。只不過對應行中被驅動表各個列的數值為NULL。
_1.外連接下過濾條件–ON
使用外連接下,過濾使用ON語句。且ON子句必須要存在。
ON語句此時用于替代WHERE。但采用ON語句過濾下,對驅動表中某行和被驅動表中所有行構成的合并行都無法通過過濾下,依然會在最終結果集產生一個合并行其中被驅動表部分采用NULL。
_2.外連接下過濾–WHERE
外連接下,必須存在ON執行過濾。但ON過濾下,對驅動表所有在被驅動表中無法產生任何匹配的行,在最終結果集中均保留一行。如果希望對這些保留行執行過濾,需要依賴WHERE子句來進行。
3.連接語法
在MySQL中,根據選取的驅動表的不同,外連接可細分為左外連接和右外連接。
左外連接,可簡稱左連接;右外連接,可簡稱右連接;
_1.左連接的語法
如:SELECT * FROM t1 LEFT [OUTER] JOIN t2 ON 過濾條件 [WHERE 過濾條件];
括號中OUTER可以省略,不影響含義。
這里t1是驅動表,t2是被驅動表。
上述語句中ON子句不可省略,可以用ON替代WHERE。也可以讓ON專注于過濾最終結果集中WHERE無法過濾的行。
_2.右連接的語法
如:SELECT * FROM t1 RIGHT [OUTER] JOIN t2 ON 連接條件 [WHERE 過濾條件];
此時驅動表是t2,t1是被驅動表。
_3.內連接的語法
下列這些語句含義一致,均采用內連接:
SELECT * FROM t1, t2;
SELECT * FROM t1 JOIN t2;
SELECT * FROM t1 INNER JOIN t2;
SELECT * FROM t1 CROSS JOIN t2;
內連接中ON子句沒有存在必要。存在下等價于WHERE看待。
4.多表連接
如:SELECT * FROM t1 INNER JOIN t2 INNER JOIN t3 WHERE t1.m1 = t2.m2 AND t1.m1 = t3.m3;
另一種效果等價寫法:SELECT * FROM t1 INNER JOIN t2 ON t1.m1 = t2.m2 INNER JOIN t3 ON t1.m1 = t3.m3;
5.表的別名
如:SELECT s1.number, s1.name, s1.major, s2.subject, s2.score FROM student_info AS s1 INNER JOIN student_score AS s2 WHERE s1.number = s2.number;
上述在FROM子句中給student_info,student_score起了別名,在查詢語句其他地方可使用別名來引用表。
6.自連接
如:SELECT * FROM t1, t1;
會報錯,報錯不是因為不允許自連接,而是因為FROM子句中不允許兩個表同名。
這樣就可以了:SELECT * FROM t1 AS table1, t1 AS table2;
`