SQL基础教程第五章笔记
第五章 復(fù)雜查詢
?
5.1 視圖
5.1.1 視圖和表?
? ? ? ?從SQL的角度來(lái)看,視圖和表是相同的。兩者的區(qū)別在于表中保存的是實(shí)際的數(shù)據(jù),而視圖中保存的是SELECT語(yǔ)句。視圖本身并不存儲(chǔ)數(shù)據(jù)。
? ? ? ?視圖的優(yōu)點(diǎn):1.視圖無(wú)需保存數(shù)據(jù)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2.將頻繁使用SELECT語(yǔ)句保存成視圖
?
代碼1.通過(guò)視圖等SELECT語(yǔ)句保存數(shù)據(jù)
SELECT shohin_bunrui,SUM(hanbai_tanka),SUM(shiire_tanka)FROM Shohin GROUP BY shohin_bunrui;輸出結(jié)果:
5.1.2 創(chuàng)建視圖的方法
代碼2.創(chuàng)建視圖時(shí)使用CREATE VIEW語(yǔ)句,語(yǔ)法如下:
CREATE VIEW 視圖名稱(<視圖列名1>,<視圖列名2>,...) AS <SELECT語(yǔ)句>? ? ? ?SELECT語(yǔ)句需要書(shū)寫(xiě)在AS關(guān)鍵字之后,SELECT語(yǔ)句中列的排列順序和視圖中列的排列順序相同。
?
代碼3.ShohinSum視圖
CREATE VIEW ShohinSum ( shohin_bunrui, cnt_shohin) AS SELECT shohin_bunrui,COUNT(*)FROM ShohinGROUP BY shohin_bunrui;輸出結(jié)果:
?
? ? ? 此處AS的定義與定義別名時(shí)使用的AS不相同。
?
代碼4.使用視圖
SELECT shohin_bunrui,cnt_shohinFROM ShohinSum;?輸出結(jié)果:
?
? ? ? ? ? 定義視圖時(shí)使用任何SELECT語(yǔ)句,即可以使用WHERE,GROUP BY,HAVING,也可以通過(guò)SELECT *來(lái)指定全部列。
?
? ? ? ? ? 使用視圖查詢:在FROM子句中使用視圖查詢有以下兩個(gè)步驟
? ? ? ? ? ?1.首先執(zhí)行定義視圖的SELECT語(yǔ)句
? ? ? ? ? ?2.根據(jù)得到的結(jié)果,再執(zhí)行在FROM子句中使用視圖的SELECT語(yǔ)句
? ? ? ? ? 使用視圖查詢通常需要執(zhí)行2條以上的SELECT語(yǔ)句。這里沒(méi)有使用2條而使用了2條以上是因?yàn)檫€可能出現(xiàn)以視圖為基礎(chǔ)創(chuàng)建出的類似于樓中樓那樣的多重視圖。
代碼5.視圖ShohinSumJim
CREATE VIEW ShohinSumJim (shohin_bunrui,cnt_shohin) AS SELECT shohin_bunrui,cnt_shohinFROM ShohinSumWHERE shohin_bunrui='辦公用品';--確認(rèn)是否創(chuàng)建出了視圖 SEELCT shohin_bunrui,cnt_shohinFROM ShohinSumnJim;
? ? ? 雖然語(yǔ)法上沒(méi)有錯(cuò)誤,但是我們還是應(yīng)該盡量避免在視圖的基礎(chǔ)上創(chuàng)建視圖。這是因?yàn)閷?duì)于大多數(shù)DBMS來(lái)說(shuō),多重視圖會(huì)降低SQL的性能。
?
5.1.3 視圖的限制1——定義視圖時(shí)不能使用ORDER BY子句
? ? ?原因是視圖和表一樣,數(shù)據(jù)行都是沒(méi)有順序的。
?
5.1.4 視圖的限制2——對(duì)視圖進(jìn)行更新
? ? ? 標(biāo)準(zhǔn)SQL規(guī)定:如果定義視圖的SELECT語(yǔ)句能夠滿足某些條件,那么這個(gè)視圖就可以被更新。下面是一些比較有代表性的條件。
? ? ? 條件:1.SELECT子句中未使用DISTINCT
? ? ? ? ? ? ? ? ?2.FROM 子句中只有一張表?
? ? ? ? ? ? ? ? ?3.未使用GROUP BY子句
? ? ? ? ? ? ? ? ?4.未使用HAVING子句
?
能夠更新視圖的情況:
代碼6.可以更新的視圖
CREATE VIEW ShohinJim (shohin_id,shohin_mei,shohin_bunrui,hanbai_tanka,shiire_tanka,torokubi) AS SELECT *FROM ShohinWHERE shohin_bunrui = '辦公用品';輸出結(jié)果:
代碼7.向視圖中添加數(shù)據(jù)行
INSERT INTO ShohinJim VALUES ('0009','印章',‘辦公用品’,95,10,'2009-11-30');輸出結(jié)果:
? ? ? ?
注意事項(xiàng):
? ? ? ? 在PostgreSQL中,執(zhí)行上面的向視圖中添加數(shù)據(jù)行代碼會(huì)出現(xiàn)錯(cuò)誤,因?yàn)镻ostgreSQL中的視圖會(huì)被初始設(shè)定為只讀
?
代碼8.允許PostgreSQL對(duì)視圖進(jìn)行更新
--PostgreSQLCREATE OR REPLACE RULE insert_rule AS ON INSERT TO ShohinJim DO INSTEAD INSERT INTO Shohin VALUES(new.shohin_id,new.shohin_mei,new.shohin_bunrui,new.hanbai_tanka,new.shiire_tanka,new.torokubi); --確認(rèn)數(shù)據(jù)是否已經(jīng)添加到視圖中了 SELECT*FROM ShohinJim;輸出結(jié)果:
?
--確認(rèn)數(shù)據(jù)是否已經(jīng)添加到原表中了 SELECT*FROM Shohin;?輸出結(jié)果:
?
?
?5.1.5 刪除視圖
代碼9.刪除視圖需要使用DROP VIEW語(yǔ)句,語(yǔ)法如下:
DROP VIEW (<視圖列名1>,<視圖列名2>,......)
代碼10.刪除視圖
DROP VIEW ShohinSum;輸出結(jié)果;
? ? ? ?在PostgreSQL中,如果想要?jiǎng)h除以視圖為基礎(chǔ)創(chuàng)建出來(lái)的多重視圖的話,由于存在關(guān)聯(lián)的視圖,所以會(huì)發(fā)生如下錯(cuò)誤:
? ? ? ? ERROR:由于存在關(guān)聯(lián)視圖,所以無(wú)法刪除視圖shohinsum
? ? ? ? DETALL:視圖shohinsumjim與視圖shohinsum相關(guān)聯(lián)
? ? ? ? HINT:刪除關(guān)聯(lián)對(duì)象請(qǐng)使用DROP...CASCADE
? ?
代碼11.在PostgreSQL中使用CASCADE選項(xiàng)來(lái)刪除關(guān)聯(lián)視圖
DROP VIEW ShohinSum CASCADE;輸出結(jié)果:
?
? ? ? ? ? ?
5.2 子查詢
? ? ? ? ?
5.2.1 子查詢和視圖
? ? ?子查詢就是一張一次性的視圖,子查詢就是將用來(lái)定義視圖的SELECT語(yǔ)句直接用于FROM子句之中。
?
代碼12.視圖ShohinSun和確認(rèn)用的SELCT語(yǔ)句
--根據(jù)商品種類統(tǒng)計(jì)商品數(shù)量的視圖 CREATE VIEW ShohinSum (shohin_bunrui,cnt_shohin) AS SELECT shohin_bunrui,COUNT(*)FROM ShohinGROUP BY Shohin_bunrui;--確認(rèn)視圖是否已經(jīng)創(chuàng)建成功 SELECT shohin_bunrui,cnt_shohinFROM ShohinSum;輸出結(jié)果:
?
代碼13.子查詢
--SQL Server、DB2、PostgreSQL、MySQL --直接在FROM子句中使用定義視圖的SELECT語(yǔ)句SELECT shohin_bunrui,cnt_shohinFROM (SELECT shohin_bunrui,COUNT(*) AS cnt_shohinFROM ShohinGROUP BY shohin_bunrui) AS ShohinSum;輸出結(jié)果:
(在Oracle中,不能使用AS。)
? ? ? ?實(shí)際上,該SELECT語(yǔ)句包含嵌套結(jié)構(gòu),首先會(huì)執(zhí)行FROM子句中的SELECT語(yǔ)句,然后才會(huì)執(zhí)行外層的SELECT語(yǔ)句。
? ? ? ?子查詢作為內(nèi)層會(huì)首先執(zhí)行。
?
? ? ? ? 增加查詢層數(shù)
? ? ? ? 子查詢?cè)趯訑?shù)原則上是沒(méi)有限制的,可以無(wú)限嵌套下去。
代碼14.嘗試增加子查詢的嵌套層數(shù)
--SQL Server、DB2、PostgreSQL、MySQLSELECT shohin_bunrui,cnt_shohinFROM (SELECT * FROM ( SELECT shohin_bunrui,COUNT(*) AS cnt_shohinFROM ShohinGROUP BY shohin_bunrui) AS ShohinSumWHERE cnt_shohin = 4 ) AS ShohinSum2;輸出結(jié)果:
(在Oracle中不能使用AS)
? ? ?隨著子查詢嵌套層數(shù)的增加,SQL語(yǔ)句變得越來(lái)越難讀懂,性能也會(huì)越來(lái)越差。因此,應(yīng)該避免使用多層嵌套的子查詢。
?
5.2.2 子查詢的名稱
? ? ? ?之前的例子中,我們給子查詢?cè)O(shè)定了“ShohinSum”等名稱。為子查詢?cè)O(shè)定名稱時(shí)需要使用AS關(guān)鍵字,該關(guān)鍵字有時(shí)可以省略。
?
?5.2.3 標(biāo)量子查詢
? ? ? ?標(biāo)量子查詢就是返回單一值的子查詢,必須而且只能返回一行一列的結(jié)果。
?
? ? ? ? 在WHERE子句中使用標(biāo)量子查詢:
? ? ? ? 我們需要查詢出銷售單價(jià)高于平均銷售單價(jià)的商品的做法
代碼15.計(jì)算平均銷售單價(jià)的標(biāo)量子查詢
SELECT AVG(hanbai_tanka)FROM Shohin;輸出結(jié)果:
代碼16.選取出銷售單價(jià)(hanbai_tanka)高于全部商品的平均單價(jià)商品
SELECT shohin_id,shohin_mei,hanbai_tankaFROM ShohinWHERE hanbai_tanka > (SELECT AVG(hanbai_tanka)FROM Shohin);輸出結(jié)果:
?
?5.2.4 標(biāo)量子查詢的書(shū)寫(xiě)位置
? ? ? 標(biāo)量子查詢的書(shū)寫(xiě)位置不僅局限于WHERE子句中,通常任何可以使用單一值的位置都可以使用。也就是說(shuō),能夠使用常數(shù)或者列名的地方,無(wú)論是SELECT子句、GROUP BY子句、HAVING子句、還是ORDER BY子句,幾乎所有地方都可以使用。
?
代碼17.在SELECT子句中使用標(biāo)量子查詢
SELECT shohin_id,shohin_mei,hanbai_tanka,(SELECT AVG(hanbai_tanka)FROM Shohin) AS avg_tankaFROM Shohin;輸出結(jié)果:
代碼18.在HAVING子句中使用標(biāo)量子查詢
SELECT shohin_bunrui,AVG(hanbai_tanka)FROM Shohin GROUP BY shohin_bunrui HAVING AVG(hanbai_tanka) > (SELECT AVG(hanbai_tanka)FROM Shohin);輸出結(jié)果:
?
5.2.5 使用標(biāo)量子查詢時(shí)的注意事項(xiàng)
? ? ? ? 子查詢返回了多行結(jié)果,那么它就不再是標(biāo)量子查詢,而僅僅是一個(gè)普通的子查詢。因此不能被用在=或者<>等需要單一輸入值的運(yùn)算符當(dāng)中,也不能在SELECT等子句當(dāng)中
?
5.3 關(guān)聯(lián)子查詢
5.3.1 普通子查詢和關(guān)聯(lián)子查詢的區(qū)別
代碼19.通過(guò)關(guān)聯(lián)子查詢按照商品種類對(duì)平均銷售單價(jià)進(jìn)行比較
--SQL、DB2、PostgreSQL,MySQL SELECT shohin_id,shohin_mei,hanbai_tankaFROM Shohin AS S1WHERE hanbai_tanka > (SELECT AVG(hanbai_tanka)FROM Shohin AS S2WHERE S1.shohin_bunrui = S2.shohin_bunruiGROUP BY shohin_bunrui);輸出結(jié)果:
這里起關(guān)鍵作用的地方就是在子查詢中添加的WHERE子句的條件
?
5.3.2 關(guān)聯(lián)子查詢也是用來(lái)對(duì)集合進(jìn)行切分的
?
5.3.3 結(jié)合條件一定要寫(xiě)在子查詢中
? ? ? 子查詢內(nèi)部設(shè)定的關(guān)聯(lián)名稱,只能在該子查詢內(nèi)部使用
? ? ? ? ? ? ? ? ??
? ??
? ? ? ?
?
轉(zhuǎn)載于:https://www.cnblogs.com/zsdeblog/p/9187437.html
總結(jié)
以上是生活随笔為你收集整理的SQL基础教程第五章笔记的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: react-navigation设置na
- 下一篇: 这么多数据包