SQL(五、複雜查詢)
來自專欄露珠學數據分析
1、視圖
從SQL角度來看,視圖和表是相同的,兩者的區別在於表中保存的是實際數據,而視圖中保存的是SELECT語句(視圖本身並不存儲數據)。
視圖的優點:(1)無需保存數據,節省存儲設備的容量;
(2)可以頻繁地使用SELECT語句保存成視圖,創建好後,只需在SELECT語句中進行調用,就可方便的得到結果,進而提高效率。
創建視圖的CREATE VIEW語句:
CREATE VIEW 視圖名稱 (視圖列名1,視圖列名2,...)
AS
SELECT語句;
例:
使用視圖
使用視圖的查詢
在FROM子句中使用視圖的查詢,通常有如下兩個步驟:
(1)首先執行定義視圖的SELECT語句
(2)根據得到的結果,再執行在FROM子句中使用視圖的SELECT語句。
多重視圖:以視圖為基礎創建的視圖。
以視圖ProductSum為基礎創建的視圖ProductSumJim
確認創建好的視圖
執行結果
多重視圖會降低SQL的性能,因此應該盡量使用單一視圖,避免在視圖的基礎上創建視圖。
視圖限制
(1)限制一:定義視圖時不能使用ORDER BY子句
(2)限制二:對視圖進行更新
註:視圖和表需要同時進行更新,通過匯總(聚合或結合)得到的視圖無法進行更新。
能夠更新視圖的情況:
向視圖中添加行
確認數據是否已添加到視圖中
原表
確認是否已添加到原表
刪除視圖
語句:DROP VIEW 視圖名稱(視圖列名1,視圖列名2,...);
例:
2、子查詢
子查詢:就是一次性視圖。
視圖是通過保存數據的SELECT語句的方法來為用戶提供便利。
子查詢是將用來定義的SElECT語句直接用於FROM子句中。
例:視圖
子查詢
子查詢和上述的視圖具有同樣的功能。
上述SELECT語句的執行順序:先執行內層FROM子句中的SELECT子句(子查詢),再執行外層的查詢(SELECT子句)。
增加子查詢的層數
例:
執行結果
隨著子循環嵌套層數的增加,SQL語句會變得越來越難懂,性能也會越來越差,因此,應避免使用多層嵌套的子查詢。
標量子查詢
標量就是單一的意思。
標量子查詢必須而且只能返回1行1列的結果,就是返回單一值的子查詢。
在WHERE子句中使用標量子查詢
由於WHERE子句中不能使用聚合函數,因此如下寫法是錯誤的
計算平均銷售單價的標量子查詢
將標量子查詢帶入到WHERE語句中,使用子查詢的SQL會從子查詢開始執行。
標量子查詢的書寫位置
標量子查詢的書寫位置通常在任何可以使用單一值的位置都可以使用。如之前學過的WHERE子句、SELECT子句、GROUP BY子句、HAVING子句以及ORDER BY子句等等。
例1:在SELECT語句中使用標量子查詢
例2:在Having子句中使用標量子查詢
使用標量子查詢時的注意事項
即:該子查詢絕對不能返回多行結果。
如下的SELECT子查詢會發生錯誤。
3、關聯子查詢
在使用關聯子查詢時,需要在表所對應的列名之前加上表的別名,以「表名.列名」的形式記述。在細分的組內進行比較時,需要使用關聯子查詢。
該結合條件的意思是,在同一商品種類中對各商品的銷售單價和平均單價進行比較。
關聯子查詢也是用來對集合進行切分的。
結合條件一定要寫在子查詢中。
上述寫法違反規則,因為關聯名稱(P1,P2)存在一個作用域的限制,子查詢內部設定的關聯名稱,只能在子查詢內部使用。而SQL是按照先內層子查詢後外層子查詢的順序來執行的,這樣,子查詢結束時只會留下執行結果,作為抽出源的P2已經不存在了(當然,原表Product還是存在的),因此,在執行外層查詢時,由於P2已經不存在了,因此就會出現不存在使用該名稱的表這樣的錯誤。
推薦閱讀:
※為什麼用SQL而不是Excel+VBA?
※MySQL常用查詢語句23條
※從MapReduce的執行來看如何優化MaxCompute(原ODPS) SQL
※sql中為什麼select要放在from之前?
※SQL常見面試題