电脑知识|欧美黑人一区二区三区|软件|欧美黑人一级爽快片淫片高清|系统|欧美黑人狂野猛交老妇|数据库|服务器|编程开发|网络运营|知识问答|技术教程文章 - 好吧啦网

您的位置:首頁技術(shù)文章
文章詳情頁

解決Mysql的left join無效及使用的注意事項說明

瀏覽:66日期:2023-10-01 12:41:46
Mysql的left join無效及使用

今天寫sql發(fā)現(xiàn)使用left join 沒有把左邊表的數(shù)據(jù)全部查詢出來,讓我郁悶了一會,后來仔細研究了一會才知道自己犯了個常識性的錯誤(我是菜鳥)

這是原sql

解決Mysql的left join無效及使用的注意事項說明

這樣的查詢并不能將tb_line這張表的數(shù)據(jù)都查詢出來,好尷尬...

后面我才知道原來當(dāng)我們進行多表查詢,在執(zhí)行到where之前,會先形成一個臨時表

而on就是臨時表中的條件篩選,使用left join則不管條件是否為真,都會查詢出左邊表的數(shù)據(jù),條件為假的,則顯示為null

解決Mysql的left join無效及使用的注意事項說明

where則是在臨時表生成之后的過濾條件

解決Mysql的left join無效及使用的注意事項說明

在第一張圖中,我將tb_vehicle這張表的過濾條件放在where之中,那left join所產(chǎn)生條件為假的數(shù)據(jù),則會在where 的 v.del_flag=’0’中被過濾掉(因為條件為假的數(shù)據(jù),del_flag都為空)

所以我看似使用了left join ,實際上這樣寫與使用inner join的結(jié)果是一樣的

正確sql如下:

解決Mysql的left join無效及使用的注意事項說明

在臨時表中就做好條件篩選,這樣就能夠得到左邊表的數(shù)據(jù)

總結(jié):

使用left join 并需要做條件查詢的時候,需要仔細斟酌改條件篩選放在on后面還是where后面

Mysql left join 避坑指南現(xiàn)象

left join在我們使用mysql查詢的過程中可謂非常常見,比如博客里一篇文章有多少條評論、商城里一個貨物有多少評論、一條評論有多少個贊等等。但是由于對join、on、where等關(guān)鍵字的不熟悉,有時候會導(dǎo)致查詢結(jié)果與預(yù)期不符,所以今天我就來總結(jié)一下,一起避坑。

這里我先給出一個場景,并拋出兩個問題,如果你都能答對那這篇文章就不用看了。

假設(shè)有一個班級管理應(yīng)用,有一個表classes,存了所有的班級;有一個表students,存了所有的學(xué)生,具體數(shù)據(jù)如下:

SELECT * FROM classes;

解決Mysql的left join無效及使用的注意事項說明

SELECT * FROM students;

解決Mysql的left join無效及使用的注意事項說明

那么現(xiàn)在有兩個需求:

找出每個班級的名稱及其對應(yīng)的女同學(xué)數(shù)量

找出一班的同學(xué)總數(shù)

對于需求1,大多數(shù)人不假思索就能想出如下兩種sql寫法,請問哪種是對的?

SELECT c.name, count(s.name) as num FROM classes c left join students s on s.class_id = c.id and s.gender = ’F’ group by c.name

或者

SELECT c.name, count(s.name) as num FROM classes c left join students s on s.class_id = c.id where s.gender = ’F’ group by c.name

對于需求2,大多數(shù)人也可以不假思索的想出如下兩種sql寫法,請問哪種是對的?

SELECT c.name, count(s.name) as num FROM classes c left join students s on s.class_id = c.id where c.name = ’一班’ group by c.name

或者

SELECT c.name, count(s.name) as num FROM classes c left join students s on s.class_id = c.id and c.name = ’一班’ group by c.name

請不要繼續(xù)往下翻 !!先給出你自己的答案,正確答案就在下面。

~

~

~

答案是兩個需求都是第一條語句是正確的,要搞清楚這個問題,就得明白mysql對于left join的執(zhí)行原理,下節(jié)進行展開。

根源

mysql 對于left join的采用類似嵌套循環(huán)的方式來進行從處理,以下面的語句為例:

SELECT * FROM LT LEFT JOIN RT ON P1(LT,RT)) WHERE P2(LT,RT)

其中P1是on過濾條件,缺失則認為是TRUE,P2是where過濾條件,缺失也認為是TRUE,該語句的執(zhí)行邏輯可以描述為:

FOR each row lt in LT {// 遍歷左表的每一行 BOOL b = FALSE; FOR each row rt in RT such that P1(lt, rt) {// 遍歷右表每一行,找到滿足join條件的行 IF P2(lt, rt) {//滿足 where 過濾條件 t:=lt||rt;//合并行,輸出該行 } b=TRUE;// lt在RT中有對應(yīng)的行 } IF (!b) { // 遍歷完RT,發(fā)現(xiàn)lt在RT中沒有有對應(yīng)的行,則嘗試用null補一行 IF P2(lt,NULL) {// 補上null后滿足 where 過濾條件 t:=lt||NULL; // 輸出lt和null補上的行 } }}

當(dāng)然,實際情況中MySQL會使用buffer的方式進行優(yōu)化,減少行比較次數(shù),不過這不影響關(guān)鍵的執(zhí)行流程,不在本文討論范圍之內(nèi)。

從這個偽代碼中,我們可以看出兩點:

如果想對右表進行限制,則一定要在on條件中進行,若在where中進行則可能導(dǎo)致數(shù)據(jù)缺失,導(dǎo)致左表在右表中無匹配行的行在最終結(jié)果中不出現(xiàn),違背了我們對left join的理解。因為對左表無右表匹配行的行而言,遍歷右表后b=FALSE,所以會嘗試用NULL補齊右表,但是此時我們的P2對右表行進行了限制,NULL若不滿足P2(NULL一般都不會滿足限制條件,除非IS NULL這種),則不會加入最終的結(jié)果中,導(dǎo)致結(jié)果缺失。

如果沒有where條件,無論on條件對左表進行怎樣的限制,左表的每一行都至少會有一行的合成結(jié)果,對左表行而言,若右表若沒有對應(yīng)的行,則右表遍歷結(jié)束后b=FALSE,會用一行NULL來生成數(shù)據(jù),而這個數(shù)據(jù)是多余的。所以對左表進行過濾必須用where。

下面展開兩個需求的錯誤語句的執(zhí)行結(jié)果和錯誤原因:

需求1

解決Mysql的left join無效及使用的注意事項說明

需求2

解決Mysql的left join無效及使用的注意事項說明

需求1由于在where條件中對右表限制,導(dǎo)致數(shù)據(jù)缺失(四班應(yīng)該有個為0的結(jié)果)

需求2由于在on條件中對左表限制,導(dǎo)致數(shù)據(jù)多余(其他班的結(jié)果也出來了,還是錯的)

總結(jié)

通過上面的問題現(xiàn)象和分析,可以得出了結(jié)論:在left join語句中,左表過濾必須放where條件中,右表過濾必須放on條件中,這樣結(jié)果才能不多不少,剛剛好。

SQL 看似簡單,其實也有很多細節(jié)原理在里面,一個小小的混淆就會造成結(jié)果與預(yù)期不符,所以平時要注意這些細節(jié)原理,避免關(guān)鍵時候出錯。

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持好吧啦網(wǎng)。

相關(guān)文章:
主站蜘蛛池模板: RTO换向阀_VOC高温阀门_加热炉切断阀_双偏心软密封蝶阀_煤气蝶阀_提升阀-湖北霍科德阀门有限公司 | 东莞螺杆空压机_永磁变频空压机_节能空压机_空压机工厂批发_深圳螺杆空压机_广州螺杆空压机_东莞空压机_空压机批发_东莞空压机工厂批发_东莞市文颖设备科技有限公司 | 游动电流仪-流通式浊度分析仪-杰普仪器(上海)有限公司 | 家用净水器代理批发加盟_净水机招商代理_全屋净水器定制品牌_【劳伦斯官网】 | 胶辊硫化罐_胶鞋硫化罐_硫化罐厂家-山东鑫泰鑫智能装备有限公司 意大利Frascold/富士豪压缩机_富士豪半封闭压缩机_富士豪活塞压缩机_富士豪螺杆压缩机 | 蔬菜配送公司|蔬菜配送中心|食材配送|饭堂配送|食堂配送-首宏公司 | 数显水浴恒温振荡器-分液漏斗萃取振荡器-常州市凯航仪器有限公司 | 百度网站优化,关键词排名,SEO优化-搜索引擎营销推广 | 洗石机-移动滚筒式,振动,螺旋,洗矿机-青州冠诚重工机械有限公司 | 河南mpp电力管_mpp电力管生产厂家_mpp电力电缆保护管价格 - 河南晨翀实业 | 活性氧化铝|无烟煤滤料|活性氧化铝厂家|锰砂滤料厂家-河南新泰净水材料有限公司 | 一技任务网_有一技之长,就来技术任务网 | 北京开源多邦科技发展有限公司官网| 家德利门业,家居安全门,别墅大门 - 安徽家德利门业有限公司 | 车充外壳,车载充电器外壳,车载点烟器外壳,点烟器连接头,旅行充充电器外壳,手机充电器外壳,深圳市华科达塑胶五金有限公司 | 涂层测厚仪_光泽度仪_uv能量计_紫外辐照计_太阳膜测试仪_透光率仪-林上科技 | 沈阳楼承板_彩钢板_压型钢板厂家-辽宁中盛绿建钢品股份有限公司 轴承振动测量仪电箱-轴承测振动仪器-测试仪厂家-杭州居易电气 | 有机肥设备生产制造厂家,BB掺混肥搅拌机、复合肥设备生产线,有机肥料全部加工设备多少钱,对辊挤压造粒机,有机肥造粒设备 -- 郑州程翔重工机械有限公司 | 北京森语科技有限公司-模型制作专家-展览展示-沙盘模型设计制作-多媒体模型软硬件开发-三维地理信息交互沙盘 | 烟气换热器_GGH烟气换热器_空气预热器_高温气气换热器-青岛康景辉 | 火锅加盟_四川成都火锅店加盟_中国火锅连锁品牌十强_朝天门火锅【官网】 | 高铝砖-高铝耐火球-高铝耐火砖生产厂家-价格【荣盛耐材】 | 斗式提升机_链式斗提机_带式斗提机厂家无锡市鸿诚输送机械有限公司 | 塑料熔指仪-塑料熔融指数仪-熔体流动速率试验机-广东宏拓仪器科技有限公司 | 超声波电磁流量计-液位计-孔板流量计-料位计-江苏信仪自动化仪表有限公司 | 高低温试验箱-模拟高低温试验箱订制-北京普桑达仪器科技有限公司【官网】 | 珠光砂保温板-一体化保温板-有釉面发泡陶瓷保温板-杭州一体化建筑材料 | 水厂污泥地磅|污泥处理地磅厂家|地磅无人值守称重系统升级改造|地磅自动称重系统维修-河南成辉电子科技有限公司 | 智能型高压核相仪-自动开口闪点测试仪-QJ41A电雷管测试仪|上海妙定 | 上海单片机培训|重庆曙海培训分支机构—CortexM3+uC/OS培训班,北京linux培训,Windows驱动开发培训|上海IC版图设计,西安linux培训,北京汽车电子EMC培训,ARM培训,MTK培训,Android培训 | 流程管理|流程管理软件|企业流程管理|微宏科技-AlphaFlow_流程管理系统软件服务商 | 123悬赏网_发布悬赏任务_广告任务平台 | 鄂泉泵业官网|(杭州、上海、全国畅销)大流量防汛排涝泵-LW立式排污泵 | 办公室家具_板式办公家具定制厂家-FMARTS福玛仕办公家具 | 软文发布-新闻发布推广平台-代写文章-网络广告营销-自助发稿公司媒介星 | 青岛球场围网,青岛车间隔离网,青岛机器人围栏,青岛水源地围网,青岛围网,青岛隔离栅-青岛晟腾金属制品有限公司 | 石英砂矿石色选机_履带辣椒色选机_X光异物检测机-合肥幼狮光电科技 | 泥沙分离_泥沙分离设备_泥砂分离机_洛阳隆中重工机械有限公司 | YT保温材料_YT无机保温砂浆_外墙保温材料_南阳银通节能建材高新技术开发有限公司 | 西安文都考研官网_西安考研辅导班_考研培训机构_西安在职考研培训 | 连续油炸机,全自动油炸机,花生米油炸机-烟台茂源食品机械制造有限公司 |