mysql left join中on后加條件判斷和where中加條件的區別


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
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)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM