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

left join中關於whereon條件的幾個知識點:

    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

root@localhost: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:左表記錄全部返回,右表篩選條件生效

root@localhost: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後面是作爲匹配條件進行篩選,篩選的是右表的內容。

root@localhost: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中對左表的限制條件,不影響返回的行數,隻影響右表的匹配內容

root@localhost: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)

root@localhost: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條件的行

root@localhost: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)

root@localhost: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)

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章