left join查詢會從左表那里返回所有的行,即使在右表中沒有匹配的行。查詢中on條件只有一個,因此不存在特殊注意之處。但是當我們on條件如果存在多個時候會出現一些與我們預期不符的查詢結果。
用戶表
mysql> select * from tab_user;
+---------+------+--------+----------+
| name | age | sex | addr |
+---------+------+--------+----------+
| daxin | 18 | male | beijing |
| mali | 28 | female | shandong |
| wangsan | 34 | male | beijing |
| lisi | 45 | male | liaoning |
| liwu | 58 | female | beijing |
| maoliu | 43 | male | anhui |
| zhouba | 62 | female | beijing |
+---------+------+--------+----------+
7 rows in set (0.00 sec)
訂單表
mysql> select * from tab_order;
+-------+-----------+
| name | gname |
+-------+-----------+
| daxin | Smartisan |
| mali | iPhone |
| liwu | Mac |
| lisi | xiaomi |
| maliu | nike |
+-------+-----------+
5 rows in set (0.00 sec)
查詢
mysql> select * from tab_user u left join tab_order o on u.name=o.name and u.name='lisi';
+---------+------+--------+----------+------+--------+
| name | age | sex | addr | name | gname |
+---------+------+--------+----------+------+--------+
| daxin | 18 | male | beijing | NULL | NULL |
| mali | 28 | female | shandong | NULL | NULL |
| wangsan | 34 | male | beijing | NULL | NULL |
| lisi | 45 | male | liaoning | lisi | xiaomi |
| liwu | 58 | female | beijing | NULL | NULL |
| maoliu | 43 | male | anhui | NULL | NULL |
| zhouba | 62 | female | beijing | NULL | NULL |
+---------+------+--------+----------+------+--------+
7 rows in set (0.00 sec)
咋一看是不是很蒙圈,為什么已經限制了u.name='lisi'卻查詢結果還有其他人呢?如果換用where約束。
mysql> select * from tab_user u left join tab_order o on u.name=o.name where u.name='lisi';
+------+------+------+----------+------+--------+
| name | age | sex | addr | name | gname |
+------+------+------+----------+------+--------+
| lisi | 45 | male | liaoning | lisi | xiaomi |
+------+------+------+----------+------+--------+
1 row in set (0.00 sec)
結論
這次確實只有lisi了。那為什么第一個查詢語句會與預期不符?回顧一下left join的定義,左邊表會返回所有行,所以left join如果對左邊表進行約束的話是不會生效的。但是,對left join的右邊表添加條件的話是生效的!