sql中left join on 多個條件需要特殊注意之處
阿新 • • 發佈:2019-01-26
定義:
LEFT JOIN 關鍵字會從左表 (table_name1) 那裡返回所有的行,即使在右表 (table_name2) 中沒有匹配的行。例如如下查詢:
SELECT column_name(s)
FROM table_name1
LEFT JOIN table_name2
ON table_name1.column_name=table_name2.column_name
此查詢中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)
查詢語句1:
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'卻查詢結果還有lisi呢?如果換用where約束,查詢語句2.
查詢語句2:
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了。那為什麼查詢語句1會與預期不符?回顧一下left join的定義,左邊表會返回所有行,所以left join如果對左邊表進行約束的話是不會生效的;但是,對left join的右邊表新增條件的話是生效的!反之,right join 同理!