一 視圖 VIEW
視圖是個虛表,如果經常要做一些固定的查詢,可以使用視圖。視圖依賴主表,主表修改,視圖會跟着更新。但是視圖不能太多,否則會影響效率,而且視圖隻能讀取,不能更新。視圖建立後,可以當一個隻讀的表使用,如果不用了就可以删除。
舉例如下
二 子查詢
SQL中嵌套查詢,不同于視圖,子查詢隻在目前SQL中使用,不能被其他SQL引用。SQL 子查詢比較直接的了解是,1)嵌套在SQL語句的SQL查詢 2) SQL是臨時表,外層SQL執行結束後就不在存在 3)先運作子查詢,生成結果,作為臨時表,結果被調用。4)子查詢可以放在in any all where 中使用,構成更加複雜的子查詢。
比如: 根據成績表找到每個課程中成績最低的學生。 方法是先從成績表中找到最低成績,然後找到學号,最後對應到學生姓名
成績表結構
首先要根據課程号找到最低分數,這裡需要用到Group by
此處,不能通過簡單加上學号這列而一次性找到符合條件的學号,因為group by 操作的時候并沒有加入學号這個變量,是以MySQL 會随機比對的學号,是以結果是錯誤的,如圖
為了能夠比對正确的結果, 需要把這兩個查詢分開寫,再合并如下圖所示
原表資料
Any All
子查詢:首先要配合比較運算符使用,any all 需要和邏輯判斷組合在一起。
下面兩個查詢顯示的是查詢比0002 課程号任意成績高和所有成績高的成績的學号
【注意事項】子查詢能夠解決比較複雜問題,但是子查詢本身會讓SQL增加運作開銷,是以一般不要嵌套太多,而且嵌套太多邏輯容易混亂,不便于排查錯誤。此外,子查詢傳回的是集合,集合是不能進行數學運算的,邏輯判斷符号右側隻能放子查詢結果,數學運算可以放到左邊。
三 标量子查詢
标量子查詢在子查詢上限制傳回且隻能傳回一個單一數值,而不是一個集合。這種查詢成為标量子查詢,是以标量子查詢的傳回值可以和比價運算符使用,可以參考前文子查詢的注意事項,二者傳回的結果是不同的。
單向标量子查詢
雙向标量子查詢
上圖中兩個子查詢傳回的都是單一結果,是以可以直接用于邏輯判斷。标量子查詢因為傳回單一值,是以可以用于select, where等位置。标量子查詢不能傳回多行結果,但是在複雜查詢中如果需要用到單一值時可以用。
四 關聯子查詢
關聯子查詢用于跨表查詢或者分組後組内查詢,在一個表裡操作不能得到結果的時候需要用到,關聯子查詢用于組内,是以傳回是集合,子查詢的别名也在子查詢内有效。每個變量的作用域是非常需要關注的地方,有可能SQL 報錯就是因為這個問題。
比如題目要求:查詢每個課程中大于對應課程的平均成績的學生。下圖子查詢中的變量在外層查詢是未定義的變量,出錯了。
正确的SQL如下:
簡單說,子查詢看成一個表,需要把兩個表關聯起來查詢,這樣就比較好了解了。
五 如何使用SQL解決問題
1.了解和重新表述問題,把問題量化流程化
2. 寫出分析思路
3.分步寫出SQL 語句,得出結果。
4. 正确排查錯誤,從業務流到SQL語句,子查詢和外層查詢分别檢查。