測試環境:
MySQL 5.7.19
HeidiSQL 9.3 數據庫界面連接工具(挺好用的)
碰到的問題是:
Select * from t1 left outer join t2 on t1.id=t2.id and t2.age>18 和 Select * from t1 left outer join t2 on t1.id=t2.id where t2.age>18 兩條語句返回結果集是否相同
之前在on后邊只寫過兩張表的連接條件,沒有考慮過左右連接on后面接列值有限制條件,所以仔細分析一下這個限制條件到底是有何效果
一、建立測試表格
1、t_basicInfo
表t_basicInfo有3列信息值,第一列標記某唯一的id,后兩列是基本信息
2、t_detailInfo
表t_detailInfo有4列信息值,前三列與表t_basicInfo表示相同信息。但此表並沒有表t_basicInfo所有的人的信息,只有部分人的詳細信息(address)。
先來看下我們平時常寫的左右連接語句,以左連接為例
#測試易於理解情況下,直接用*把所有列信息輸出,在非測試條件下不要用*。
Select * from t_basicInfo t1 left outer join t_detailInfo t2 on t1.id = t2.id
輸出結果如下:
以上就是我們最常用的左連接語法,但是在on后加上限制條件會如何?
二、在on后添加除了連接條件外的其他限制條件
測試一下對不同的條件進行限制篩選結果如何:
①對id列(連接列)進行限制
②對t1中name進行限制
③對t2中name進行限制
1、對id進行限制
(1)對t1.id限制
Select * from t_basicInfo t1 left outer join t_detailInfo t2 on t1.id = t2.id and t1.id > 2
查詢結果如下:
(2)對t2.id限制
Select * from t_basicInfo t1 left outer join t_detailInfo t2 on t1.id = t2.id and t2.id > 2
查詢結果如下:
結果分析:查詢結果相同。在on后對連接條件中的列(id)進行限制只會對副表(t2)中的信息進行限制,t1中的數據行數並沒有減少
還不能下結論,接着測試
2、對t1中的列(非關聯列)進行限制
Select * from t_basicInfo t1 left outer join t_detailInfo t2 on t1.id = t2.id and t1.age > 19
查詢結果如下:
結果分析:在t1中的列進行限制后,只把滿足條件的t1行進行左連接,t1中的數據行數並沒有減少。
3、對t2中的列(非關聯列)進行限制
Select * from t_basicInfo t1 left outer join t_detailInfo t2 on t1.id = t2.id and t2.address != 'Shanghai'
查詢結果如下:
結果分析:在t2中的列進行限制后,只把t2滿足條件的列進行左連接,t1中的數據行數並沒有減少。
結論:
結合1/2/3中的測試結果:如果在on后加上限制條件,會在連接時考慮限制條件,如果不符合條件,則本行數據不進行連接動作。作為主表所有數據必出現在結果集中,而副表不進行連接的行數據一定不出現在結果集中。
上個圖來說明一下
三、回到我們最初的問題
Select * from t_basicInfo t1 left outer join t_detailInfo t2 on t1.id = t2.id and t1.id > 2
和
Select * from t_basicInfo t1 left outer join t_detailInfo t2 on t1.id = t2.id where t1.id > 2
如果將and換成where,結果集是什么?
第一條語句是二、(1)中的測試語句,我把結果重現拿下來以便對比
然后第二句的結果運行結果如下:
仔細考慮一下原因,然后看結論:
如果on后的and換成了where。where后的限制條件已經不是在t1和t2表進行連接的時候進行限制,而是對 在t1和t2表進行t1.id=t2.id條件下進行關聯的結果集再進行select * from(連接結果集) where t1.id>2.
如有錯誤,還望指正!