1. 程式人生 > >mysql left join中where和on條件的區別

mysql left join中where和on條件的區別

行記錄 影響 知識 區別 where 相同 beijing 兩張 滿足

left join中關於where和on條件的幾個知識點:
    1.多表left join是會生成一張臨時表,並返回給用戶
    2.where條件是針對最後生成的這張臨時表進行過濾,過濾掉不符合where條件的記錄,是真正的不符合就過濾掉。
    3.on條件是對left join的右表進行條件過濾,但依然返回左表的所有行,右表中沒有的補為NULL
    4.on條件中如果有對左表的限制條件,無論條件真假,依然返回左表的所有行,但是會影響右表的匹配值。也就是說on中左表的限制條件只影響右表的匹配內容,不影響返回行數。
結論:
    1.where條件中對左表限制,不能放到on後面
    2.where條件中對右表限制,放到on後面,會有數據行數差異,比原來行數要多

測試:
創建兩張表:
CREATE TABLE t1(id INT,name VARCHAR(20));
insert  into `t1`(`id`,`name`) values (1,‘a11‘);
insert  into `t1`(`id`,`name`) values (2,‘a22‘);
insert  into `t1`(`id`,`name`) values (3,‘a33‘);
insert  into `t1`(`id`,`name`) values (4,‘a44‘);

CREATE TABLE t2(id INT,local VARCHAR(20));
insert  into `t2`(`id`,`local`) values (1,‘beijing‘);
insert  into `t2`(`id`,`local`) values (2,‘shanghai‘);
insert  into `t2`(`id`,`local`) values (5,‘chongqing‘);
insert  into `t2`(`id`,`local`) values (6,‘tianjin‘);

測試01:返回左表所有行,右表符合on條件的原樣匹配,不滿足條件的補NULL
[email protected]:cuigl 11:04:25 >SELECT t1.id,t1.name,t2.local FROM t1 LEFT JOIN t2 ON t1.id=t2.id;
+------+------+----------+
| id   | name | local    |
+------+------+----------+
|    1 | a11  | beijing  |
|    2 | a22  | shanghai |
|    3 | a33  | NULL     |
|    4 | a44  | NULL     |
+------+------+----------+
4 rows in set (0.00 sec)

測試02:on後面增加對右表的限制條件:t2.local=‘beijing‘
結論02:左表記錄全部返回,右表篩選條件生效
[email protected]:cuigl 11:19:42 >SELECT t1.id,t1.name,t2.local FROM t1 LEFT JOIN t2 ON t1.id=t2.id and t2.local=‘beijing‘;
+------+------+---------+
| id   | name | local   |
+------+------+---------+
|    1 | a11  | beijing |
|    2 | a22  | NULL    |
|    3 | a33  | NULL    |
|    4 | a44  | NULL    |
+------+------+---------+
4 rows in set (0.00 sec)

測試03:只在where後面增加對右表的限制條件:t2.local=‘beijing‘
結論03:針對右表,相同條件,在where後面是對最後的臨時表進行記錄篩選,行數可能會減少;在on後面是作為匹配條件進行篩選,篩選的是右表的內容。
[email protected]:cuigl 11:20:07 >SELECT t1.id,t1.name,t2.local FROM t1 LEFT JOIN t2 ON t1.id=t2.id where t2.local=‘beijing‘;   
+------+------+---------+
| id   | name | local   |
+------+------+---------+
|    1 | a11  | beijing |
+------+------+---------+
1 row in set (0.01 sec)

測試04:t1.name=‘a11‘ 或者 t1.name=‘a33‘
結論04:on中對左表的限制條件,不影響返回的行數,只影響右表的匹配內容
[email protected]:cuigl 11:24:46 >SELECT t1.id,t1.name,t2.local FROM t1 LEFT JOIN t2 ON t1.id=t2.id and t1.name=‘a11‘;  
+------+------+---------+
| id   | name | local   |
+------+------+---------+
|    1 | a11  | beijing |
|    2 | a22  | NULL    |
|    3 | a33  | NULL    |
|    4 | a44  | NULL    |
+------+------+---------+
4 rows in set (0.00 sec)
[email protected]:cuigl 11:25:04 >SELECT t1.id,t1.name,t2.local FROM t1 LEFT JOIN t2 ON t1.id=t2.id and t1.name=‘a33‘;
+------+------+-------+
| id   | name | local |
+------+------+-------+
|    1 | a11  | NULL  |
|    2 | a22  | NULL  |
|    3 | a33  | NULL  |
|    4 | a44  | NULL  |
+------+------+-------+
4 rows in set (0.00 sec)

測試05:where t1.name=‘a33‘ 或者 where t1.name=‘a22‘
結論05:where條件是在最後臨時表的基礎上進行篩選,顯示只符合最後where條件的行
[email protected]:cuigl 11:25:15 >SELECT t1.id,t1.name,t2.local FROM t1 LEFT JOIN t2 ON t1.id=t2.id where t1.name=‘a33‘;   
+------+------+-------+
| id   | name | local |
+------+------+-------+
|    3 | a33  | NULL  |
+------+------+-------+
1 row in set (0.00 sec)
[email protected]:cuigl 11:27:27 >SELECT t1.id,t1.name,t2.local FROM t1 LEFT JOIN t2 ON t1.id=t2.id where t1.name=‘a22‘;
+------+------+----------+
| id   | name | local    |
+------+------+----------+
|    2 | a22  | shanghai |
+------+------+----------+
1 row in set (0.00 sec)

  

mysql left join中where和on條件的區別