)FROM<表名>其中,計(jì)數(shù)規(guī)范包括:-*:計(jì)數(shù)所有選擇的行,包括NULL值;-ALL列名:計(jì)數(shù)指定列的所有非空值行,如果不寫(xiě)" />

日韩久久久精品,亚洲精品久久久久久久久久久,亚洲欧美一区二区三区国产精品 ,一区二区福利

SQL語(yǔ)句匯總(三)——聚合函數(shù)、分組、子查詢

系統(tǒng) 1900 0

拖了一個(gè)星期,終于開(kāi)始寫(xiě)第三篇了。走起!

?

聚合函數(shù):

SQL中提供的聚合函數(shù)可以用來(lái)統(tǒng)計(jì)、求和、求最值等等。

分類:

–COUNT:統(tǒng)計(jì)行數(shù)量
–SUM:獲取單個(gè)列的合計(jì)值
–AVG:計(jì)算某個(gè)列的平均值
–MAX:計(jì)算列的最大值
–MIN:計(jì)算列的最小值
?
首先,創(chuàng)建數(shù)據(jù)表如下:
SQL語(yǔ)句匯總(三)——聚合函數(shù)、分組、子查詢及組合查詢
?
?
執(zhí)行列、行計(jì)數(shù)(count):
標(biāo)準(zhǔn)格式
          
            SELECT
          
          
            COUNT
          
          (
          
            <
          
          計(jì)數(shù)規(guī)范
          
            >
          
          ) 
          
            FROM
          
          
            <
          
          表名
          
            >
          
        

其中,計(jì)數(shù)規(guī)范包括:

- * :計(jì)數(shù)所有選擇的行,包括NULL值;

- ALL 列名:計(jì)數(shù)指定列的所有非空值行,如果不寫(xiě),默認(rèn)為ALL;

- DISTINCT 列名:計(jì)數(shù)指定列的唯一非空值行。

例,計(jì)算班里共有多少學(xué)生:
          
            SELECT
          
          
            COUNT
          
          (
          
            *
          
          ) 
          
            FROM
          
           t_student;
        

?

也可加入篩選條件,如求女學(xué)生數(shù)目:

          
            SELECT
          
          
            COUNT
          
          (
          
            *
          
          ) 
          
            FROM
          
           t_student 
          
            WHERE
          
           student_sex
          
            =
          
          
            '
          
          
          
            '
          
          ;
        
如果要計(jì)算班級(jí)數(shù)目,就需要用到DISTINCT:
          
            SELECT
          
          
            COUNT
          
          (
          
            DISTINCT
          
           student_class) 
          
            FROM
          
           t_student;
        

DISTINCT即去重,如果不加DISTINCT則結(jié)果為表行數(shù)——5。

?
返回列合計(jì)值(SUM):
注:sum只要ALL與DISTINCT兩種計(jì)數(shù)規(guī)范,無(wú)*。
計(jì)算學(xué)生年齡之和:
          
            SELECT
          
          
            SUM
          
          (student_age) 
          
            FROM
          
           t_student;
        

?

返回列平均值(AVG):

計(jì)算 學(xué)生平均年齡:

          
            SELECT
          
          
            AVG
          
          (student_age)
          
            FROM
          
           t_student;
        

?

返回最大值/最小值(MAX/MIN):

年齡最大的學(xué)生信息(最小值同理):

          
            SELECT
          
          
            MAX
          
          (student_age) 
          
            FROM
          
           t_student;
        

注:這里只能求出最大年齡,要想顯示年齡最大的學(xué)生全部信息,需要用到之后的子查詢。

?

數(shù)據(jù)分組(GROUP BY):

SQL中數(shù)據(jù)可以按列名分組,搭配聚合函數(shù)十分實(shí)用。

例,統(tǒng)計(jì)每個(gè)班的人數(shù):

          
            SELECT
          
           student_class,
          
            COUNT
          
          (
          
            ALL
          
           student_name) 
          
            AS
          
           總?cè)藬?shù) 
          
            FROM
          
           t_student 
          
            GROUP
          
          
            BY
          
           (student_class);
        

AS為定義別名,別名的使用在組合及聯(lián)接查詢時(shí)會(huì)有很好的效果,之后再說(shuō)。

?

分組中也可以加入篩選條件WHERE,不過(guò)這里一定要注意的是,執(zhí)行順序?yàn)椋篧HERE過(guò)濾→分組→聚合函數(shù)。牢記!

統(tǒng)計(jì)每個(gè)班上20歲以上的學(xué)生人數(shù):

          
            SELECT
          
           student_class,
          
            COUNT
          
          (student_name) 
          
            AS
          
           總?cè)藬?shù) 
          
            FROM
          
           t_student 
          
            WHERE
          
           student_age 
          
            >
          
          
            20
          
          
            GROUP
          
          
            BY
          
           (student_class);
        

?

HAVING過(guò)濾條件:

之前說(shuō)了分組操作、聚合函數(shù)、WHERE過(guò)濾的執(zhí)行順序,那如果我們希望在聚合之后執(zhí)行過(guò)濾條件怎么辦?

例,我們想查詢平均年齡在20歲以上的班級(jí)

能用下面的語(yǔ)句嗎?

          
            SELECT
          
           student_class, 
          
            AVG
          
          (student_age) 
          
            FROM
          
           t_student 
          
            WHERE
          
          
            AVG
          
          (student_age)
          
            >
          
          
            20
          
          
            GROUP
          
          
            BY
          
           student_class;
        
結(jié)果會(huì)出錯(cuò)。正因?yàn)榫酆虾瘮?shù)在WHERE之后執(zhí)行,所以這里在WHERE判斷條件里加入聚合函數(shù)是做不到的。
這里使用HAIVING即可完成:
          
            SELECT
          
           student_class,
          
            AVG
          
          (student_age) 
          
            AS
          
           平均年齡 
          
            FROM
          
           t_student 
          
            GROUP
          
          
            BY
          
           (student_class) 
          
            HAVING
          
          
            AVG
          
          (student_age)
          
            >
          
          
            20
          
          ; 
        

?
這里再啰嗦一句
SQL的執(zhí)行順序:
–第一步:執(zhí)行FROM
–第二步:WHERE條件過(guò)濾
–第三步:GROUP BY分組
–第四步:執(zhí)行SELECT投影列
–第五步:HAVING條件過(guò)濾
–第六步:執(zhí)行ORDER BY 排序
?
子查詢:
為什么要子查詢?
現(xiàn)有一數(shù)據(jù)表如下:
SQL語(yǔ)句匯總(三)——聚合函數(shù)、分組、子查詢及組合查詢
根據(jù)之前的知識(shí)我們可以查出每門(mén)科目的最高分,但是要想查出取得最高分的學(xué)生信息就做不到了。這時(shí)就需要用到子查詢來(lái)取得完整的信息。
?
什么是子查詢?子查詢就是嵌套在主查詢中的查詢。
子查詢可以嵌套在主查詢中所有位置,包括SELECT、FROM、WHERE、GROUP BY、HAVING、ORDER BY。
但并不是每個(gè)位置嵌套子查詢都是有意義并實(shí)用的,這里對(duì)幾種有實(shí)際意義的子查詢進(jìn)行說(shuō)明。
現(xiàn)有表兩張:一張學(xué)生表、一張班表。id相關(guān)聯(lián)
SQL語(yǔ)句匯總(三)——聚合函數(shù)、分組、子查詢及組合查詢
SQL語(yǔ)句匯總(三)——聚合函數(shù)、分組、子查詢及組合查詢
?
在SELECT中嵌套:
學(xué)生信息和班級(jí)名稱位于不同的表中,要在同一張表中查出學(xué)生的學(xué)號(hào)、姓名、班級(jí)名稱:
          
            SELECT
          
           s.student_id,s.student_name,(
          
            SELECT
          
           class_name 
          
            FROM
          
           t_class c 
          
            WHERE
          
           c.class_id
          
            =
          
          s.class_id) 
          
            FROM
          
           t_student s 
          
            GROUP
          
          
            BY
          
           s.student_id;         
        

* 首先這條SQL語(yǔ)句用到了別名,寫(xiě)法為在FORM的表名后加上某個(gè)字符比如FROM t_student s,這樣在之后調(diào)用t_student的某一列時(shí)就可以用s.student_id來(lái)強(qiáng)調(diào)此列來(lái)源于對(duì)應(yīng)別名的那張表。

別名在子查詢及聯(lián)接查詢中的應(yīng)用有著很好效果,當(dāng)兩張表有相同列名或者為了加強(qiáng)可讀性,給表加上不同的別名,就能很好的區(qū)分哪些列屬于哪張表。

還有種情況就是在子查詢或聯(lián)接查詢時(shí),主查詢及子查詢均為對(duì)同一張表進(jìn)行操作,為主、子查詢中的表加上不同的別名能夠很好的區(qū)分哪些列的操作是在主查詢中進(jìn)行的,哪些列的操作是在子查詢中進(jìn)行的,下文會(huì)有實(shí)例說(shuō)明。

接下來(lái)回到上面的SQL語(yǔ)句中,可以看出本條子查詢的嵌套是在SELECT位置(括號(hào)括起來(lái)的部分),它與學(xué)號(hào)、學(xué)生姓名以逗號(hào)分隔開(kāi)并列在SELECT位置,也就是說(shuō)它是我們想要查出的一列,
子查詢中查出的是,班級(jí)表中的班級(jí)id與學(xué)生表中的班級(jí)id相同的行 ,注意? WHERE c.class_id=s.class_id 這里就是別名用法的一個(gè)很好的體現(xiàn),區(qū)分開(kāi)了兩張表中同樣列名的列。
結(jié)果:
最后的GROUP BY可以理解為對(duì)重復(fù)行的去重,如果不加:
SQL語(yǔ)句匯總(三)——聚合函數(shù)、分組、子查詢及組合查詢
?
在WHERE中嵌套:
現(xiàn)要查出C語(yǔ)言成績(jī)最高的學(xué)生的信息:
          
            SELECT
          
          
            *
          
          
            FROM
          
           t_student 
          
            WHERE
          
           student_subject
          
            =
          
          
            '
          
          
            C語(yǔ)言
          
          
            '
          
          
            AND
          
           student_score
          
            >=ALL
          
           (
          
            SELECT
          
           student_score 
          
            FROM
          
           t_student 
          
            WHERE
          
           student_subject
          
            =
          
          
            '
          
          
            C語(yǔ)言
          
          
            '
          
          ) ;
        

結(jié)果:

這里出現(xiàn)了一個(gè)ALL,其為子查詢運(yùn)算符
分類:
–ALL運(yùn)算符
  和子查詢的結(jié)果逐一比較,必須全部滿足時(shí)表達(dá)式的值才為真。
–ANY運(yùn)算符
  和子查詢的結(jié)果逐一比較,其中一條記錄滿足條件則表達(dá)式的值就為真。
–EXISTS/NOT EXISTS運(yùn)算符
  EXISTS判斷子查詢是否存在數(shù)據(jù),如果存在則表達(dá)式為真,反之為假。NOT EXISTS相反。
在子查詢或相關(guān)查詢中,要求出某個(gè)列的最大值,通常都是用ALL來(lái)比較,大意為比其他行都要大的值即為最大值。
要查出C語(yǔ)言成績(jī)比李四高的學(xué)生的信息:
            
              SELECT
            
            
              *
            
            
              FROM
            
             t_student 
            
              WHERE
            
             student_subject
            
              =
            
            
              '
            
            
              C語(yǔ)言
            
            
              '
            
            
              AND
            
             student_score 
            
              >
            
            (
            
              SELECT
            
             student_score 
            
              FROM
            
             t_student 
            
              WHERE
            
             student_name
            
              =
            
            
              '
            
            
              李四
            
            
              '
            
            
              AND
            
             student_subject
            
              =
            
            
              '
            
            
              C語(yǔ)言
            
            
              '
            
            ); 
          

通過(guò)上面兩例,應(yīng)該可以明白子查詢?cè)赪HERE中嵌套的作用。通過(guò)子查詢中返回的列值來(lái)作為比較對(duì)象,在WHERE中運(yùn)用不同的比較運(yùn)算符來(lái)對(duì)其進(jìn)行比較,從而得到結(jié)果。

現(xiàn)在我們回到最開(kāi)始的問(wèn)題,怎么查出每門(mén)課最高成績(jī)的學(xué)生的信息:

            
              SELECT
            
            
              *
            
            
              FROM
            
             t_student s1 
            
              WHERE
            
             s1.student_score 
            
              >=
            
            
              ALL
            
            (
            
              SELECT
            
             s2.student_score 
            
              FROM
            
             t_student s2 
            
              WHERE
            
             s1.`student_subject`
            
              =
            
            s2.student_subject);
          

這里就是上文提到的別名的第二種用法,主、子查詢對(duì)同一張表操作,區(qū)分開(kāi)位于內(nèi)外表中相同的列名。

結(jié)果:

?

子查詢的分類:

–相關(guān)子查詢
  執(zhí)行依賴于外部查詢的數(shù)據(jù)。
  外部查詢返回一行,子查詢就執(zhí)行一次。
–非相關(guān)子查詢
  獨(dú)立于外部查詢的子查詢。
  子查詢總共執(zhí)行一次,執(zhí)行完畢后后將值傳遞給外部查詢。
?
上文提到的例子中,第一個(gè)例子求學(xué)生對(duì)應(yīng)班級(jí)名的即為相關(guān)子查詢,其中WHERE c.class_id=s.class_id 即為相關(guān)條件。其他的例子均只對(duì)一張表進(jìn)行操作,為非相關(guān)子查詢。
需要注意的是相關(guān)子查詢主查詢執(zhí)行一回,子查詢就執(zhí)行一回,十分耗費(fèi)時(shí)間,尤其是當(dāng)數(shù)據(jù)多的時(shí)候。

?

組合查詢:

通過(guò)UNION運(yùn)算符來(lái)將兩張表縱向聯(lián)接,基本方式為:

            
              SELECT
            
             列1 , 列2 
            
              FROM
            
            
               表1


            
            
              UNION
            
            
              SELECT
            
             列3 , 列4 
            
              FROM
            
             表2;
          

UNION ALL為保留重復(fù)行:

            
              SELECT
            
             列1 , 列2 
            
              FROM
            
            
               表1


            
            
              UNION
            
            
              ALL
            
            
              SELECT
            
             列3 , 列4 
            
              FROM
            
             表2;
          
組合查詢并不是太實(shí)用,所以這里只是簡(jiǎn)單提一下,不舉出例子了。
?
上文說(shuō)過(guò)相關(guān)子查詢不推薦使用,組合查詢又用的少之又少,那需要關(guān)聯(lián)的多張表我們?cè)趺醋觯?
這就是下一篇博文要詳細(xì)說(shuō)明的SQL的重點(diǎn)表聯(lián)接、聯(lián)接查詢。而此篇博文目的是為了對(duì)嵌套查詢、別名的用法等等打下基礎(chǔ),畢竟只是寫(xiě)法變了,思路還是相似的。
?
感謝您的瀏覽,希望能對(duì)您有所幫助。

SQL語(yǔ)句匯總(三)——聚合函數(shù)、分組、子查詢及組合查詢


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號(hào)聯(lián)系: 360901061

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對(duì)您有幫助就好】

您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長(zhǎng)會(huì)非常 感謝您的哦!!!

發(fā)表我的評(píng)論
最新評(píng)論 總共0條評(píng)論
主站蜘蛛池模板: 乌鲁木齐县| 固始县| 岗巴县| 伊春市| 汉源县| 措美县| 中西区| 昭苏县| 潼南县| 桐梓县| 大余县| 垣曲县| 达孜县| 合水县| 南城县| 山阴县| 邮箱| 新邵县| 西峡县| 嘉禾县| 汝城县| 万山特区| 大丰市| 大庆市| 宝鸡市| 绥芬河市| 泰宁县| 万山特区| 曲水县| 岑巩县| 西峡县| 东至县| 福建省| 万源市| 东平县| 彭州市| 英吉沙县| 黔江区| 道真| 韶关市| 项城市|