上一篇對三個join的語句做了一個區別,如果連最基礎的都不清楚,那么請先參考:inner join 與 left join 和right join之間的區別
碰巧在項目中遇到了一個sql,是left join和where的條件限制的區別,想了好半天,這里做一下筆記,萬一以后忘記了方便查看。
話不多說,直接上測試數據和sql,然后對我的理解進行分析下。
student表和grade表
簡單提一個需求是:我需要統計所有有成績的學生信息。項目遇到那個問題比這個復雜,但是最終需要篩選的條件和這個大致相同,這里就舉個栗子。
這里分析一下,既然是學生信息,那么,肯定就是以student為主表,關聯的為grade表,寫出下面條件。
SELECT stu.* FROM student stu LEFT JOIN grade gra on stu.id = gra.c_stuId AND gra.c_fs IS NOT NULL
查詢結果如下:
仔細看看上面的sql,和需求,好像也沒有什么錯誤呀,分數不為空,我的確是加了限制條件了啊, LEFT JOIN grade gra on stu.id = gra.c_stuId AND gra.c_fs IS NOT NULL
但是看看需求,是分數不為空的學生,但是李四的成績的確是空的,結果還是查出來了,咦,那么就奇怪了,問題出在哪里了呢。
這就回到之前我們所說的,left join並不會影響主表,也就是說,無論LEFT JOIN on后面什么條件,主表學生成績都會被查出來,所以說,這里的限制條件沒用。
這時候就需要where這個老大上場了。將上面查詢sql修改如下:
SELECT stu.* FROM student stu LEFT JOIN grade gra on stu.id = gra.c_stuId WHERE gra.c_fs is NOT null
查詢結果如下:
咦,是吧,達到了預期的目的,id為3的學生分數是空的,那么最后查詢出來的也沒有包含他。這就是where的厲害之處。
那么,到底是為什么呢,我們說下,on只是對局部條件做限制,而where是對全局做限制,什么是全局做限制呢,也就是相當於,對最后查詢出來的整個結果做限制。其實我們可以把
所有的字段都查出來,然后看一下,就一目了然了。
為了方便我就直接截圖說明:
加上gra.*一看就知道,查詢出來的整個數據就是如上所示,而where的作用是什么呢,是對全局進行限制,就相當於上面查詢出來的又是一個新的表,我來對這個做限制。
如圖所示:
where加上就相當於對這個結果集再次進行限制,把分數為空的去掉了,最終結果如下:
但是因為我們查詢的時候,如上圖所示紅色方框所顯示的,並沒有查詢出來,所以並不能一目了然的看到分數這個字段,因此會產生一開始所看到的那種情況,另外也是因為之間沒接
觸過,以前以為where條件只能針對主表字段去做一個篩選,並不能篩選從表的,現在經過上面一個小案例之后,算是有了一個大概的理解了,不知道有沒有對你產生幫助,歡迎下方
評論,一起探討。!!