數(shù)據(jù)庫學(xué)習(xí)筆記(五)2017.9.22

寫在前面:本篇博客大部分內(nèi)容參考數(shù)據(jù)庫系統(tǒng)概念(本科教學(xué)版)第三章(第三章部分的多表操作沒有在此處講亭珍,準(zhǔn)備挪到第四章再一起討論)
筆者接下來的代碼示例會主要在SQL Server數(shù)據(jù)庫中測試


在開始今天的摸魚大業(yè)之前,讓我們先構(gòu)造一組表筝闹,用于演示下面的例子(′`)

BONUS.png
DEPT.png
EMP.png
SALGRADE.png

Having 子句

由于where子句中不能用聚合函數(shù)(組函數(shù))做條件航夺,故引入having子句

  • 讓我們先看一下各個(gè)子句的書寫順序(下面的只是我們一般在寫SQL語句時(shí)候的書寫順序)
    • SELECT
    • FROM
    • WHERE
    • GROUP BY
    • HAVING
    • ORDER BY
    • 上面各子句的執(zhí)行順序:FROM-->WHERE-- > GROUP BY--> HAVING-->SELECT-->ORDER BY

    其中上面除了GROUP BY和HAVING可以互換位置外蕉朵,其他位置均固定,但最好采用上面的順序

  • 從上面的討論中可以看出
    • HAVING一般緊隨GROUP BY之后阳掐,置于ORDER BY之前
    • 而且當(dāng)聚集函數(shù)(組函數(shù))做條件時(shí)始衅,只用用HAVING來處理
  • 舉個(gè)栗子:求所有平均工資大于2000的部門的部門號以及該部門的平均工資
    • 先來看看每個(gè)部門的平均工資
      SELECT DEPTNO, avg(SAL) as avg_sal
      FROM EMP
      GROUP BY DEPTNO
      
      得到如下結(jié)果
    • 1.png
    • 接下來開始求題設(shè)的問題
      SELECT DEPTNO, avg(SAL) as avg_sal
      FROM EMP
      GROUP BY DEPTNO
      HAVING avg(SAL) > 2000;
      
      得到如下結(jié)果
    • 2.png

聚合函數(shù)的嵌套

  • 不同數(shù)據(jù)庫對聚集函數(shù)嵌套的規(guī)定不同
    • Oracle數(shù)據(jù)庫規(guī)定最多只能有兩層嵌套
    • SQL Server不允許聚集函數(shù)嵌套
  • 舉個(gè)栗子:
    --下面的語句在Oracle數(shù)據(jù)庫中執(zhí)行是可以的
    SELECT max(avg(sal))
    FROM EMP
    GROUP BY deptno
    
    --上面的語句在SQL Server中執(zhí)行會報(bào)下面的錯(cuò)
    [S0001][130] 不能對包含聚合或子查詢的表達(dá)式執(zhí)行聚合函數(shù)冷蚂。
    
  • ┐(′?_?`)┌ 實(shí)際上二層以上的嵌套也是毫無意義的(只是瞎嗶嗶,不是什么重點(diǎn)汛闸,有助于理解為什么聚集函數(shù)多層嵌套是沒有意義的)
    • 首先回憶一下蝙茶,聚集函數(shù)的操作是多行輸入,得到一行輸出
    • 舉個(gè)栗子
      SELECT max(max(avg(sal)))
      FROM EMP
      GROUP BY deptno
      
    • 現(xiàn)在來分析上面語句執(zhí)行的過程
      • (avg)首先根據(jù)部門號deptno分成若干組诸老,并計(jì)算每組的平均工資(返回若干條記錄)
      • (max)然后取各部門最高的平均工資(返回一條記錄)
      • (max)這個(gè)時(shí)候只有一條記錄隆夯,取最大值也還是那一條記錄

子查詢

這部分是重點(diǎn)也是難點(diǎn)呀?(?`^′?)?,不用擔(dān)心别伏,讓筆者帶你細(xì)細(xì)解剖(?_? )
這部分參考了兩份筆記和課本

  • 嵌套子查詢

    即SQL標(biāo)準(zhǔn)提供嵌套子查詢機(jī)制蹄衷,允許將一個(gè)完整的select-from-where查詢表達(dá)式嵌入到另一個(gè)查詢語句中

  • 子查詢嵌套在where和having子句中的情況(把子查詢整體當(dāng)做一組值,可以是0個(gè)畸肆,1個(gè)宦芦,或多個(gè))

    • 單行子查詢
      • 在單行子查詢中,子查詢語句只能返回一行數(shù)據(jù)
      • 當(dāng)where子句中用下列邏輯符號連接子查詢時(shí)轴脐,便只能連接單行子查詢
        • =
        • <
        • >
        • <=
        • >=
        • <>
      • 舉個(gè)栗子(?_? )
        • 我們現(xiàn)在要找所有員工中调卑,拿到最高工資的人的名字以及工資
        SELECT ENAME, SAL
        FROM EMP
        WHERE SAL = (SELECT max(SAL)
                     FROM EMP);
        
        得到如下結(jié)果
      • 3.png
    • 多行子查詢
      • 多行子查詢中,子查詢語句可以返回多行數(shù)據(jù)
      • 當(dāng)where子句中用下列關(guān)鍵字連接子查詢時(shí)大咱,便是多行子查詢($代表上面提到的=, >等符號)
        • $ any/some
        • $ all
      • 舉幾個(gè)簡單的栗子
        • < any(...) 表示小于子查詢結(jié)果集中的最大值
        • > any(...) 表示大于子查詢結(jié)果集中的最小值
        • = any(...) 等價(jià)于in
        • = all(...) 沒有語法錯(cuò)誤恬涧,但是只要子查詢結(jié)果集的個(gè)數(shù)大于1,則整體的結(jié)果必然為空
        • < all(...) 表示小于子查詢結(jié)果集中的最小值
        • > all(...) 表示大于子查詢結(jié)果集中的最大值
      • 來舉個(gè)正經(jīng)的栗子
        • 比部門號為20的部門的所有員工的工資都要高的員工的名字和工資
        SELECT ENAME, SAL
        FROM EMP
        WHERE SAL > SOME (SELECT SAL
                        FROM EMP
                        WHERE DEPTNO = 10);
        
        得到如下結(jié)果
      • 4.png
      • 還有一個(gè)要注意的問題(?_?)碴巾,就是子查詢中SELECT后面的字段要根據(jù)主查詢語句中的字段來確定(簡單的說就是子查詢語句前面溯捆,where后面,出現(xiàn)了什么字段厦瓢,子查詢語句的SELECT列表中理論上就應(yīng)該出現(xiàn)這些字段)
        • 舉個(gè)栗子
        --下面這個(gè)語句是匹配的
        SELECT ENAME, SAL
        FROM EMP
        WHERE SAL > SOME (SELECT SAL
                        FROM EMP
                        WHERE DEPTNO = 10);
        --下面這個(gè)語句就不匹配的
        --因?yàn)镋NAM并沒有出現(xiàn)在主查詢語句中
        SELECT ENAME, SAL
        FROM EMP
        WHERE SAL > SOME (SELECT ENAME, SAL
                        FROM EMP
                        WHERE DEPTNO = 10);
        
        • 其實(shí)換個(gè)角度想想提揍,具體執(zhí)行的時(shí)候是將where后面的字段與子查詢語句的結(jié)果集進(jìn)行比較,如果字段都不一樣煮仇,就沒有可比性了
      • 對了劳跃,還有一個(gè)補(bǔ)充,not in + 子查詢浙垫,如果子查詢的結(jié)果集中包含NULL值刨仑,那整體的結(jié)果必為空。因?yàn)镹ULL值是不確定的值夹姥,誰也不能保證某個(gè)具體的值是否等于NULL杉武。。辙售。
    • 子查詢中存在性的判別可以用exists關(guān)鍵字
      • 舉個(gè)栗子就好
      --下面的語句就查出了所有手底下管了人的經(jīng)理的信息
      --其實(shí)這里已經(jīng)用到了相關(guān)子查詢轻抱,具體的下面將會講到
      SELECT *
      FROM EMP as e
      WHERE exists(SELECT 1
                   FROM EMP
                  WHERE EMP.MGR = e.EMPNO);
      
    • 試思考下面兩個(gè)問題,根據(jù)提示理解一下旦部,也可以實(shí)際操作驗(yàn)證一下
      • =some 等價(jià)于 in十拣, 然而 <>some不等價(jià)于not in(<>some表示的是只要不等于結(jié)果集中的任意元素即可封拧,可想而知,只要結(jié)果集中有大于一個(gè)元素夭问,這個(gè)條件是恒成立的
      • <>all 等價(jià)于 not in,然而=all不等價(jià)于in
  • 相關(guān)子查詢

    • 慎用曹铃,因?yàn)橐坏┦褂孟嚓P(guān)子查詢缰趋,子查詢語句可能會被執(zhí)行很多次,很影響效率
    • 舉個(gè)栗子
    --下面的語句找出了所有比自己部門平均工資高的員工的信息
    --檢索時(shí)陕见,每檢索一行數(shù)據(jù)秘血,子查詢語句就要被執(zhí)行一次
    --(因?yàn)樵撟硬樵冋Z句只有在某個(gè)具體的部門號下才會有結(jié)果
    --而,要獲取部門號评甜,就必須依賴于主查詢語句中的某行具體數(shù)據(jù))
    SELECT ENAME, SAL, DEPTNO
    FROM EMP e
    WHERE SAL > (SELECT avg(EMP.SAL)
                 FROM EMP
                WHERE e.DEPTNO = EMP.DEPTNO);
    
    • 舉個(gè)上面舉過的栗子
    --下面的語句就查出了所有手底下管了人的經(jīng)理的信息
    --用exists時(shí)灰粮,只要找到數(shù)據(jù)即會返回,不會繼續(xù)向下檢索
    SELECT *
    FROM EMP as e
    WHERE exists(SELECT 1
                 FROM EMP
                WHERE EMP.MGR = e.EMPNO);
    

    由于exists會在找到數(shù)據(jù)后立即返回忍坷,而不是繼續(xù)向下檢索粘舟,所以用exists的相關(guān)子查詢效率會稍微高一丟丟

    • 可以自己驗(yàn)證一下下面結(jié)論
      • not exists 不受空值的影響
      • not in 受空值的影響
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市佩研,隨后出現(xiàn)的幾起案子柑肴,更是在濱河造成了極大的恐慌,老刑警劉巖旬薯,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晰骑,死亡現(xiàn)場離奇詭異,居然都是意外死亡绊序,警方通過查閱死者的電腦和手機(jī)硕舆,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來骤公,“玉大人抚官,你說我怎么就攤上這事×苎” “怎么了耗式?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長趁猴。 經(jīng)常有香客問我刊咳,道長,這世上最難降的妖魔是什么儡司? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任娱挨,我火速辦了婚禮,結(jié)果婚禮上捕犬,老公的妹妹穿的比我還像新娘跷坝。我一直安慰自己酵镜,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布柴钻。 她就那樣靜靜地躺著淮韭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪贴届。 梳的紋絲不亂的頭發(fā)上靠粪,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天,我揣著相機(jī)與錄音毫蚓,去河邊找鬼占键。 笑死,一個(gè)胖子當(dāng)著我的面吹牛元潘,可吹牛的內(nèi)容都是我干的畔乙。 我是一名探鬼主播,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼翩概,長吁一口氣:“原來是場噩夢啊……” “哼牲距!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起氮帐,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤嗅虏,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后上沐,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體皮服,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年参咙,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了龄广。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,137評論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡蕴侧,死狀恐怖择同,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情净宵,我是刑警寧澤敲才,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站择葡,受9級特大地震影響紧武,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜敏储,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一阻星、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧已添,春花似錦妥箕、人聲如沸滥酥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽坎吻。三九已至,卻和暖如春呛讲,著一層夾襖步出監(jiān)牢的瞬間禾怠,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工贝搁, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人芽偏。 一個(gè)月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓雷逆,卻偏偏與公主長得像,于是被迫代替她去往敵國和親污尉。 傳聞我的和親對象是個(gè)殘疾皇子膀哲,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容

  • 1.簡介 數(shù)據(jù)存儲有哪些方式?電子表格被碗,紙質(zhì)文件某宪,數(shù)據(jù)庫。 那么究竟什么是關(guān)系型數(shù)據(jù)庫锐朴? 目前對數(shù)據(jù)庫的分類主要是...
    喬震閱讀 1,723評論 0 2
  • 5.多表查詢 多表查詢 目的:從多張表獲取數(shù)據(jù) 前提:進(jìn)行連接的多張表中有共同的列 等連接 通過兩個(gè)表具有相同意義...
    喬震閱讀 1,238評論 0 0
  • 寫在前面:本篇博客大部分內(nèi)容參考數(shù)據(jù)庫系統(tǒng)概念(本科教學(xué)版)第四章(第三章的多表部分會挪到這一部分講)筆者接下來的...
    SunnyQjm閱讀 513評論 0 2
  • 查詢是數(shù)據(jù)的一個(gè)重要操作兴喂。用戶發(fā)送查詢請求,經(jīng)編譯軟件變異成二進(jìn)制文件供服務(wù)器查詢焚志,后返回查詢結(jié)果集給用戶衣迷,查詢會...
    產(chǎn)品小正閱讀 1,390評論 0 2
  • 每個(gè)人的青春里壶谒,都有一些可是告訴又或者不能告訴的秘密,而這些秘密里膳沽,總有一部分是關(guān)于那些年在你視野里不斷出現(xiàn)...
    一森姑娘閱讀 295評論 0 0