參考:https://blog.csdn.net/lj1994104/article/details/79671807
一,MySQL連接查詢類型
A)內連接:join,inner join
B)外連接:left join,left outer join,right join,right outer join,union
C)交叉連接:cross join
二,下面以示例進行分析
創建兩張表,把表當成一個集合那么表中的元素就是集合的一個元素
創建a表
CREATE TABLE `a` ( `id` int(10) NOT NULL AUTO_INCREMENT, `age` int(2) DEFAULT NULL, PRIMARY KEY (`id`) ) ;
創建b表
CREATE TABLE `b` ( `id` int(10) NOT NULL AUTO_INCREMENT, `name` varchar(32) DEFAULT NULL, PRIMARY KEY (`id`) ) ;
插入測試數據
2.1內連接inner join或者join(等同與inner join)
mysql> select * from a inner join b on a.id=b.id; +----+------+----+-------+ | id | age | id | name | +----+------+----+-------+ | 2 | 11 | 2 | zhang | | 3 | 12 | 3 | li | | 4 | 13 | 4 | zhou | +----+------+----+-------+
應用場景
這種場景下得到的是滿足某一條件的A,B內部的數據;本次需要滿足的條件是a.id等於b。id
正因為得到的是內部共有數據,所以連接方式稱為內連接。
2.2外連接(6種場景)
2.2.1 left join 或者left outer join(等同於left join)
mysql> select * from a left join b on a.id=b.id; +----+------+------+-------+ | id | age | id | name | +----+------+------+-------+ | 2 | 11 | 2 | zhang | | 3 | 12 | 3 | li | | 4 | 13 | 4 | zhou | | 1 | 10 | NULL | NULL | +----+------+------+-------+
Table B中不存在的記錄填充NULL
應用場景
2.2.2 [left join 或者left outer join(等同於left join)] + [where B.column is null]
mysql> select * from a left join b on a.id=b.id where b.id is null; +----+------+------+------+ | id | age | id | name | +----+------+------+------+ | 1 | 10 | NULL | NULL | +----+------+------+------+
應用場景
這種場景下得到的是A中的所有數據減去"與B滿足同一條件 的數據",然后得到的A剩余數據;
2.2.3 right join 或者fight outer join(等同於right join)
mysql> select * from a right join b on a.id=b.id; +------+------+----+-------+ | id | age | id | name | +------+------+----+-------+ | 2 | 11 | 2 | zhang | | 3 | 12 | 3 | li | | 4 | 13 | 4 | zhou | | NULL | NULL | 5 | chen | +------+------+----+-------+
應用場景
這種場景下得到的是B的所有數據,和滿足某一條件的A的數據;
2.2.4 [left join 或者left outer join(等同於left join)] + [where A.column is null]
mysql> select * from a right join b on a.id=b.id where a.id is null; +------+------+----+------+ | id | age | id | name | +------+------+----+------+ | NULL | NULL | 5 | chen | +------+------+----+------+
應用場景
這種場景下得到的是B中的所有數據減去 "與A滿足同一條件 的數據“,然后得到的B剩余數據;
2.2.5 full join (mysql不支持,但是可以用 left join union right join代替)
mysql> select * from a left join b on a.id=b.id union select * from a right join b on a.id=b.id; +------+------+------+-------+ | id | age | id | name | +------+------+------+-------+ | 2 | 11 | 2 | zhang | | 3 | 12 | 3 | li | | 4 | 13 | 4 | zhou | | 1 | 10 | NULL | NULL | | NULL | NULL | 5 | chen | +------+------+------+-------+
union過后,重復的記錄會合並(id為2,3,4的三條記錄),
應用場景
這種場景下得到的是滿足某一條件的公共記錄,和獨有的記錄
2.2.6 full join + is null(mysql不支持,但是可以用 (left join + is null) union (right join+isnull代替)
mysql> select * from a left join b on a.id=b.id where b.id is null union select * from a right join b on a.id=b.id where a.id is null; +------+------+------+------+ | id | age | id | name | +------+------+------+------+ | 1 | 10 | NULL | NULL | | NULL | NULL | 5 | chen | +------+------+------+------+
應用場景
這種場景下得到的是A,B中不滿足某一條件的記錄之和
2.3交叉連接(cross join)
2.3.1 實際應用中還有這樣一種情形,想得到A,B記錄的排列組合,即笛卡兒積,這個就不好用集合和元素來表示了。需要用到cross join:
mysql> select * from a cross join b; +----+------+----+-------+ | id | age | id | name | +----+------+----+-------+ | 1 | 10 | 2 | zhang | | 2 | 11 | 2 | zhang | | 3 | 12 | 2 | zhang | | 4 | 13 | 2 | zhang | | 1 | 10 | 3 | li | | 2 | 11 | 3 | li | | 3 | 12 | 3 | li | | 4 | 13 | 3 | li | | 1 | 10 | 4 | zhou | | 2 | 11 | 4 | zhou | | 3 | 12 | 4 | zhou | | 4 | 13 | 4 | zhou | | 1 | 10 | 5 | chen | | 2 | 11 | 5 | chen | | 3 | 12 | 5 | chen | | 4 | 13 | 5 | chen | +----+------+----+-------+
2.3.2 還可以為cross join指定條件 (where):
mysql> select * from a cross join b where a.id=b.id; +----+------+----+-------+ | id | age | id | name | +----+------+----+-------+ | 2 | 11 | 2 | zhang | | 3 | 12 | 3 | li | | 4 | 13 | 4 | zhou | +----+------+----+-------+
注:這種情況實際上實現了內連接
三 注意事項
上面仍然存在遺漏,那就是mysql對sql語句的容錯問題,即在sql語句不完全符合書寫建議的情況,mysql會允許這種情況,盡可能地解釋它:
3.1 一般cross join后面加上where條件,但是用cross join+on也是被解釋為cross join+where;
3.2 一般內連接都需要加上on限定條件,如上面場景2.1;如果不加會被解釋為交叉連接;
3.3 如果連接表格使用的是逗號,會被解釋為交叉連接;
注:sql標准中還有union join和natural inner join,mysql不支持,而且本身也沒有多大意義,其結果可以用上面的幾種連接方式得到