mysql left join中where和on條件的區別
阿新 • • 發佈:2017-10-18
行記錄 影響 知識 區別 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條件的區別