參考資料:
《SQL基礎(chǔ)教程》
視圖
視圖和表
從SQL的角度來看蛾扇,視圖就是一張表,兩者的區(qū)別在于是否保存了實際的數(shù)據(jù)魏滚。
- 創(chuàng)建表時镀首,會通過
INSERT
語句將數(shù)據(jù)保存到數(shù)據(jù)庫中,而數(shù)據(jù)庫中的數(shù)據(jù)實際上會保存到計算機的存儲設(shè)備鼠次。 - 使用視圖時更哄,并不會將數(shù)據(jù)保存到任何地方,實際上視圖保存的是
SELECT
語句腥寇。從視圖讀取數(shù)據(jù)時成翩,視圖會在內(nèi)部執(zhí)行該SELECT
語句并創(chuàng)建出一張臨時表。
總結(jié)成一句話:表中存儲的是實際數(shù)據(jù)赦役,視圖本質(zhì)上就是SELECT
語句麻敌。
視圖的優(yōu)點
- 視圖無需保存數(shù)據(jù),節(jié)省存儲設(shè)備容量掂摔;
- 可以將頻繁使用的
SELECT
語句保存成視圖术羔,就不用每次都重新書寫了。
創(chuàng)建和使用視圖
創(chuàng)建視圖的CREATE VIEW
語句
CREATE VIEW 視圖名稱 (<視圖列名1>, <視圖列名2>, ...)
AS
<SELECT語句>
注意:SELECT
語句中列的排列順序和視圖中列的排列順序相同乙漓,SELECT
語句中的第1列就是視圖中的第1列级历,以此類推。視圖的列名在視圖名稱之后的列表中定義叭披。
創(chuàng)建ProductSum視圖
CREATE VIEW ProductSum (product_type, cnt_product)
AS
SELECT product_type, COUNT(*)
FROM Product
GROUP BY product_type;
使用視圖
SELECT
product_type,
cnt_product
FROM ProductSum;
執(zhí)行結(jié)果:
在FROM
子句中使用視圖查詢的兩個步驟
- 創(chuàng)建視圖:執(zhí)行定義視圖的
SELECT
語句寥殖; - 使用視圖:根據(jù)得到的結(jié)果,再執(zhí)行在
FROM
子句中使用視圖的SELECT
語句。
當然嚼贡,我們還可以以視圖為基礎(chǔ)再創(chuàng)建視圖熏纯,因此,使用視圖的查詢通常需要執(zhí)行2條以上的SELECT
語句粤策。但是樟澜,多重視圖會降低SQL的性能,因此希望大家使用單一視圖掐场。
視圖的限制
定義視圖時不能使用ORDER BY
子句
為什么不能使用ORDER BY
子句往扔?
因為視圖和表一樣贩猎,數(shù)據(jù)行都是沒有順序的熊户。
對視圖進行更新
在SELECT
語句中,視圖可以和表一樣使用吭服,那么嚷堡,更新語句(INSERT
、DELETE
艇棕、UPDATE
)呢蝌戒?
標準SQL中規(guī)定:如果定義視圖的SELECT
語句能夠滿足某些條件,那么這個視圖就可以被更新沼琉。
幾個具有代表性的條件:
-
SELECT
子句中未使用DISTINCT
-
FROM
子句中只有一張表 - 未使用
GROUP BY
子句 - 未使用
HAVING
子句
刪除視圖
刪除視圖的DROP VIEW
語句
DROP VIEW 視圖名稱
刪除視圖ProductSum
DROP VIEW ProductSum;
子查詢
子查詢和視圖
子查詢就是一次性的視圖(SELECT
語句)北苟,子查詢在SELECT
語句執(zhí)行完畢之后就會消失。
子查詢
-- 和上面使用ProductSum視圖實現(xiàn)相同功能的子查詢語句
SELECT
product_type,
cnt_product
FROM (
SELECT
product_type,
COUNT(*) AS cnt_product
FROM Product
GROUP BY product_type
) AS ProductSum;
執(zhí)行結(jié)果:
子查詢SELECT
語句的執(zhí)行順序
由內(nèi)到外:
- 首先執(zhí)行
FROM
子句中的SELECT
語句打瘪; - 根據(jù)1的結(jié)果執(zhí)行外層的
SELECT
語句友鼻。
注意:子查詢的層數(shù)原則上沒有限制,可以無限嵌套下去闺骚,但是彩扔,隨著層數(shù)增加,SQL語句會變得越來越難讀懂僻爽,性能也會越來越差虫碉。因此,盡量避免使用多層嵌套的子查詢胸梆。
子查詢的名稱
原則上子查詢必須設(shè)定名稱敦捧,設(shè)定名稱是需要使用AS
關(guān)鍵字,有時也可以省略碰镜。
標量子查詢
標量子查詢就是返回單一值的子查詢绞惦,必須而且只能返回表中某一行的某一列的值。
在WHERE
子句中使用標量子查詢
如何查詢出銷售單價高于平均銷售單價的商品洋措?
我們可能會想到以下錯誤的SQL語句:
-- 在WHERE子句中不能使用聚合函數(shù)
SELECT
product_id,
product_name,
sale_price
FROM Product
WHERE sale_price > AVG(sale_price);
雖然這樣的SELECT
語句看上去能夠滿足我們的要求济蝉,但是由于在WHERE
子句中不能使用聚合函數(shù),因此這樣的SELECT
語句是錯誤的。
這時王滤,標量子查詢就可以發(fā)揮它的功效了贺嫂。
計算平均銷售單價的標量子查詢
SELECT AVG(sale_price)
FROM Product;
執(zhí)行結(jié)果:
選出銷售單價高于平均單價的商品
SELECT
product_id,
product_name,
sale_price
FROM Product
WHERE sale_price > (SELECT AVG(sale_price)
FROM Product);
執(zhí)行結(jié)果:
標量子查詢的書寫位置
通常任何可以使用單一值的位置都可以使用標量子查詢,也就是說雁乡,能夠使用常數(shù)或者列名的地方第喳,無論是SELECT
子句、GROUP BY
子句踱稍、HAVING
子句曲饱,還是ORDER BY
子句,都可以使用珠月。
注意:如果子查詢返回了多行結(jié)果扩淀,那么它就不再是標量子查詢,而僅僅只是一個普通的子查詢啤挎,因此不能被用在需要單一輸入值的地方驻谆。
關(guān)聯(lián)子查詢
通過關(guān)聯(lián)子查詢按照商品種類對平均銷售單價進行比較
SELECT
product_id,
product_name,
sale_price
FROM Product AS P1
WHERE sale_price > (SELECT AVG(sale_price)
FROM Product AS P2
WHERE P1.product_type = P2.product_type);
執(zhí)行結(jié)果:
這里起關(guān)鍵作用的就是在子查詢中添加WHERE
子句的條件,該條件的意思就是庆聘,在同一商品種類中對各商品的銷售單價和平均單價進行比較胜臊。
我的博客即將同步至騰訊云+社區(qū),邀請大家一同入駐:
https://cloud.tencent.com/developer/support-plan?invite_code=1979ipzwsgq9u