Sql Service的藝術(三) SQL聚合函數的應用

来源:https://www.cnblogs.com/liuchenxing/archive/2018/01/15/8287144.html
-Advertisement-
Play Games

SQL提供的聚合函數有求和,最大值,最小值,平均值,計數函數等。 聚合函數及其功能: 學習本節所需要的兩張表: CREATE TABLE TEACHER ( ID INT IDENTITY (1,1) PRIMARY KEY , --主鍵,自增長 TNO INT NOT NULL, --教工號 TN ...


    SQL提供的聚合函數有求和,最大值,最小值,平均值,計數函數等。

聚合函數及其功能:

函數名稱 函數功能
SUM() 返回選取結果集中所有值的總和
MAX() 返回選取結果集中所有值的最大值
MIN() 返回選取結果集中所有值的最小值
AVG() 返回選取結果集中所有值的平均值
COUNT() 返回選取結果集中行的數目

  學習本節所需要的兩張表:

CREATE TABLE TEACHER
(
    ID INT IDENTITY (1,1) PRIMARY KEY ,  --主鍵,自增長
    TNO INT NOT NULL, --教工號
    TNAME CHAR(10) NOT NULL, --教師姓名
    CNO INT NOT NULL, --課程號
    SAL INT, --工資
    DNAME CHAR(10) NOT NULL, --所在系
    TSEX CHAR(2) NOT NULL, --性別
    AGE INT NOT NULL --年齡
)
INSERT INTO dbo.TEACHER VALUES( 1,'王軍',4,400,'數學','',32)
INSERT INTO dbo.TEACHER VALUES( 2,'李彤',5,6600,'生物','',54)
INSERT INTO dbo.TEACHER VALUES( 3,'王永軍',1,1000,'電腦','',45)
INSERT INTO dbo.TEACHER VALUES( 4,'劉曉婧',2,8000,'電腦','',23)
INSERT INTO dbo.TEACHER VALUES( 5,'高維',8,6000,'電子工程','',54)
INSERT INTO dbo.TEACHER VALUES( 6,'李偉',7,230,'機械工程','',23)
INSERT INTO dbo.TEACHER VALUES( 7,'劉輝',3,0,'生物','',65)
INSERT INTO dbo.TEACHER VALUES( 8,'劉偉',9,500,'電腦','',23)
INSERT INTO dbo.TEACHER VALUES( 9,'劉靜',12,0,'經濟管理','',45)
INSERT INTO dbo.TEACHER VALUES( 10,'劉奕鍇',13,70000,'電腦','',65)
INSERT INTO dbo.TEACHER VALUES( 11,'高維',14,70000,'經濟管理','',61)

CREATE TABLE COURSE
(
    ID INT IDENTITY (1,1) PRIMARY KEY ,  --主鍵,自增長
    CNO INT NOT NULL, --課程號
    CNAME CHAR(30) NOT NULL, --課程名稱
    CTIME INT NOT NULL, --學時
    SCOUNT INT NOT NULL, --容納人數
    CTEST SMALLDATETIME NOT NULL, --考試時間
)
INSERT INTO dbo.COURSE VALUES( 4,'應用數學基礎',48,120,'2006-7-10')
INSERT INTO dbo.COURSE VALUES( 5,'生物工程概論',32,80,'2006-7-8')
INSERT INTO dbo.COURSE VALUES( 1,'電腦軟體基礎',32,70,'2006-7-8')
INSERT INTO dbo.COURSE VALUES( 2,'電腦硬體基礎',24,80,'2006-6-28')
INSERT INTO dbo.COURSE VALUES( 8,'模擬電路設計',28,90,'2006-7-10')
INSERT INTO dbo.COURSE VALUES( 7,'機械設計實踐',48,68,'2006-7-14')
INSERT INTO dbo.COURSE VALUES( 3,'生物化學',32,40,'2006-7-2')
INSERT INTO dbo.COURSE VALUES( 9,'資料庫設計',16,80,'2006-7-1')
INSERT INTO dbo.COURSE VALUES( 6,'設計理論',28,45,'2006-6-30')
INSERT INTO dbo.COURSE VALUES( 10,'電腦入門',25,150,'2006-6-29')
INSERT INTO dbo.COURSE VALUES( 11,'數字電路設計基礎',30,125,'2006-6-20')
INSERT INTO dbo.COURSE VALUES( 12,'數字電路設計基礎%',30,125,'2006-6-20')
INSERT INTO dbo.COURSE VALUES( 13,'_設計理論',28,45,'2006-6-30')
數據表

  

  一、求和函數——SUM()

--求所有老師的工資總和
    SELECT SUM(SAL) AS TOTAL_SAL FROM dbo.TEACHER

  註意:

    SUM()函數只能作用於數值類型數據。

     對某列求和,如果存在NULL值,則SUM函數會忽略該值。

 

  二、計數函數——COUNT()

   --使用COUNT(),對錶的總行數
    SELECT COUNT(*) AS TOTAL FROM dbo.TEACHER

    --使用COUNT(),對錶列的數據計數
    --SAL列有一行數據為空,所以結果與其他兩列不同
    SELECT COUNT(TNAME) AS TOTAL,COUNT(SAL) AS TOTAL,COUNT(DNAME) AS TOTAL FROM dbo.TEACHER

    --使用COUNT(),對錶的列的數據一起包含查詢,需要用到CAST,以及"+"連接符
    --ZongLie 是包含SAL和TNAME兩列的數據,放在一起查詢的
    SELECT COUNT(TNAME) AS Total_Name,COUNT(SAL) AS Total_Sal,COUNT(DNAME) AS Total_Name,COUNT(CAST(SAL AS VARCHAR(10))+TNAME) AS ZongLie FROM dbo.TEACHER

    --使用COUNT(),滿足where條件的查詢
    SELECT COUNT(*) AS TOTAL FROM dbo.TEACHER WHERE TSEX=''
  

  註意一下兩點:

    COUNT(*),計算表中行的總數,即使表中行的數據為null,也被計入在內。
    COUNT(column),計算column列包含行的數目,如果該列中某行數據為null,則該行不計入總數。

 

  三、最大/最小值函數——MAX()/MIN()

    --MAX()的使用,查詢工資最高/最低
    SELECT MAX(SAL) AS 最高工資,MIN(SAL) AS 最低工資 FROM dbo.TEACHER
  
--以下是兩種錯誤的寫法,聚合函數的處理是數據組,他將teacher看作是一個組,而TNAME,SAL的數據沒有進行分組,所以select語句沒有邏輯意義。
    --該列沒有包含在聚合函數或 GROUP BY 子句中。
    SELECT TNAME,MAX(SAL) FROM dbo.TEACHER
    --聚合不應出現在 WHERE 子句中,除非該聚合位於 HAVING 子句或選擇列表所包含的子查詢中,並且要對其進行聚合的列是外部引用。
    SELECT * FROM dbo.TEACHER WHERE AGE=MAX(AGE)
  
--那麼接下來演示正確子句使用MAX/MIN查詢
    --子句中要寫完整的select查詢語句
    SELECT TNO,TNAME,SAL,DNAME,AGE FROM dbo.TEACHER WHERE AGE=(SELECT MAX(AGE) FROM dbo.TEACHER)  --顯示年齡最大老師的信息
  
--MAX()/MIN()不僅可以用作於數值類型數據,也可以用作於字元串或者日期類型
    --字元串類型是根據字母A~Z排序的:
    SELECT MAX(TNAME) FROM dbo.TEACHER   --結果:王永軍   開頭字母:W

    --MAX()/MIN()用於時間類型
    SELECT MAX(CTEST) AS 近,MIN(CTEST) AS 遠 FROM dbo.COURSE
  

  註意:

    確認列中的最大值/最小值時,MAX,MIN函數會忽略NULL值。但是,如果該列所有行的值都是NULL,則函數返回NULL。

 

  四、均值函數--AVG()

    --均值函數是用來計算列的數據平均值的,跟SUM()一樣,只能用來計算數值類型
    SELECT AVG(SAL) AS 平均工資 FROM dbo.TEACHER     --計算工資的平均值
  
--利用COUNT() SUM() AVG()來看下求平均值的過程
    SELECT AVG(SAL) AS AVG函數算的平均工資,COUNT(*) AS 總人數,SUM(SAL)/COUNT(TNAME) AS 總的工資除總的人數 FROM dbo.TEACHER
    --運行結果發現,AVG算的平均工資跟手動算的不一樣,因為AVG算平均工資的時候忽略了“NULL”,所排除了一個人數,
    --而我們平常不管有沒有工資,都要把這個人算上在求平均,所以導致結果不一樣,網上也有有不同說法,可自行斟酌,僅代表個人想法
    

    SELECT SUM(SAL) AS 工資總和 FROM dbo.TEACHER   --162730   162730/12=13560  
    SELECT COUNT(SAL) AS 工資列的總行數排除NULL FROM dbo.TEACHER   --11     162730/11=14793 工資有一個為空,忽略
    SELECT COUNT(TNAME) AS 人數列的總行數排除NULL FROM dbo.TEACHER  --12
    SELECT COUNT(*) AS 表的總行數 FROM dbo.TEACHER  --12
    SELECT * FROM dbo.TEACHER  --表數據
  
--帶where子句使用條件限制平均值
    SELECT AVG(SAL) FROM dbo.TEACHER WHERE DNAME='電子工程'   --這個結果同上
    SELECT * FROM dbo.TEACHER WHERE DNAME='電子工程' 
  

    --聚合分析的重值處理
    SELECT COUNT(ALL SAL) AS 所有的 FROM dbo.TEACHER
    SELECT COUNT(DISTINCT SAL) AS 除去重覆的 FROM dbo.TEACHER
    SELECT * FROM dbo.TEACHER  --表數據
    --使用ALL後,計算出所有行數,使用distinct後,排除了重覆的數值
    --除了"COUNT(*)"函數外,其他函數在計算的過程中都忽略了NULL,排除NULL進行分析計算
  
--聚合函數也可以組合使用,即在一條select語句中,可以使用多個聚合函數
    SELECT COUNT(*) AS 行數,MIN(AGE) AS 最小年齡,MAX(SAL) AS 最高工資,AVG(AGE) AS 平均年齡,SUM(SAL)/COUNT(*) AS 平均工資 FROM dbo.TEACHER
  

 

  五、組合查詢GROUP BY,HAVING

--GROUP BY子句分組查詢
    SELECT TSEX+'教師' AS 老師,AVG(SAL) AS 平均工資 FROM dbo.TEACHER GROUP BY TSEX  --男 女老師的平均工資
    --來分析一下DBMS執行實例的步驟
    --首先執行FROM子句,將表TEACHER作為中間表
    --如果有WHERE子句,DBMS則根據其中的搜索條件,從中間表中去除那些值為False的列.這裡沒有WHERE子句,所以DBMS跳過了這個步驟
    --根據GROUP BY子句制定的分組列即TSEX,DBMS將中間表中的數據進行分組。這裡TSEX的值為‘男’,另一組中TSEX值為‘女’
    --DBNS為每個行組計算SELECT子句中的值,併為每組生成查詢結果中的一行。對於TSEX值為‘男’的行組,SELECT子句首先執行‘TSEX+教師’,得到‘男教師’列值,再執行‘AVG(SAL)’,求得該行組中的SAL的均值,將這兩個值作為結果表中的一條記錄;同樣,對TESX值為‘女’的行組,進行類似的操作得到另一條記錄
  
--GROUP BY子句根據多列組合行
    SELECT DNAME,TSEX,COUNT(*) AS 人數 FROM dbo.TEACHER GROUP BY DNAME,TSEX   --查詢各系男女老師的人數
    --會發現有的沒有男或女,因為沒有值,系統預設為NULL,不顯示了
    --GROUP BY子句中的NULL處理
    SELECT SAL AS 工資,COUNT(*) AS 數量 FROM dbo.TEACHER GROUP BY SAL
  
--HAVING子句
    --GROUP BY子句會根據所選的列進行分組,但實際上,我們往往還需要刪除那些不滿足條件的行組,為了實現這個功能SQL提供了HAVING子句。
    --通常GROUP BY與HAVING使用
    SELECT DNAME AS 系,COUNT(*) AS 數量 FROM dbo.TEACHER GROUP BY DNAME HAVING COUNT(*)>=2   --選擇系的數量大於等2
    --如果指定了GROUP BY子句,那麼HAVING子句定義的搜索條件將作用於這個GROUP BY子句創建的那些組
    --如果指定的WHERE子句而沒有指定GROUP BY子句,那麼HAVING子句定義的搜索條件將作用於WHERE子句的輸出,並把這個輸出看作是一個組
    --如果既沒有指定GROUP BY子句也沒有指定WHERE子句,那麼HAVING子句定義的搜索條件將作用於FROM子句的輸出並把這個輸出看作一個組
    SELECT * FROM dbo.TEACHER

    --HAVING與where子句不同的作用
    SELECT DNAME AS 系,COUNT(TSEX) AS 數量 FROM dbo.TEACHER WHERE TSEX='' GROUP BY DNAME   --女老師的系擁有女老師的數量
    --不能把單個的TSEX的值應用於組,包括HAVING子句中的列必須是組列。因此,在這種情況下,WHERE子句就不可能用HAVING子句代替
    --在數據的分組聚合分析中,HAVING子句與WHERE子句也可以共存。WHERE子句在分組之前過濾,而HAVING子句則過濾分組後的數據

    SELECT DNAME AS 系,COUNT(TSEX) AS 數量 FROM dbo.TEACHER WHERE TSEX='' GROUP BY DNAME HAVING COUNT(TSEX)>=2  --女老師的系擁有至少2個女老師的數量
    --通常情況下,HANVING子句都與GROUP BY子句一起使用,這樣就可以聚合相關數據,然後篩選這些數據,以進一步細化搜索。但如果沒有GROUP BY子句,HAVING子句也可以單獨使用。
  
--HAVING子句的單獨使用
    SELECT COUNT(TSEX) FROM dbo.TEACHER WHERE TSEX='' HAVING COUNT(TSEX)>3  --數量大於3的女老師
  


  註意:

    GROUP BY子句依據column列里的數據對行進行分組,即具有相同值得行被劃為一組。它一般與聚合函數同時使用。當然,這裡的SUM函數也可以是其他聚合函數。
    所有的組合列(GROUP BY子句中列出的列)必須來自於FROM子句列出的表,不能根據實際值、聚合函數結果或者其他表達式計算的值來對行分組。

 

  來總結一下SELECT語句查詢子句:

  SELECT語句查詢子句及其所有子句

順序號 子句關鍵詞 子句功能
1 SELECT 從指定表中取出指定列的數據
2 FROM 制定要查詢操作的表
3 WHERE 用來規定一種選擇查詢的標準
4 GROUP BY 對結果集進行分組,常與聚合函數一起使用
5 HAVING 返回選取的結果集中行的數目
6 ORDER BY 指定分組的搜尋條件

  如果在同一個SELECT語句中用到上表的一下查詢子句,則各查詢順序排列由低到高的順序。因此,完整的SELECT查詢語句可以如下:

    --SELECT select_list
    --FROM table_source
    --[WHERE search_condition]
    --[GROUP BY group_by_expression]
    --[HAVING search_condition]
    --[ORDER BY order_expression [ASC \ DESC]]
    --[]是可選項

--至少有兩名女教師的系擁有的女教師數量,並且按數量排序 SELECT DNAME AS 系名,COUNT(TSEX) AS 數量 FROM dbo.TEACHER WHERE TSEX
='' GROUP BY DNAME HAVING COUNT(TSEX)>=2 ORDER BY 數量
  

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、簡介 MongoDB是一款強大、靈活、且易於擴展的通用型資料庫 1、易用性 1)MongoDB是一款面向文檔的資料庫,而不是關係型資料庫,因此而有著更好的擴展性。 2)通過在文檔中嵌入文檔和數組,面向文檔的方法能夠僅使用一條記錄來表現複雜的層級關係。 3)MongoDB沒有預定義模式(prede ...
  • 一、新增欄位 alert table user add( userName VARCHAR2(255 CHAR) ) ; 設置欄位不為空, 給出預設值 alert table user add( userName varchar2(255 CHAR) default '這是預設值' not null ...
  • 現觀察線上系統運行發現,線上某些業務查詢存在等待時間長問題,後核查發現,部分問題出現在對資料庫操作上Cost大部分時間,後根據網上各位前輩提供的優化技巧解決大部分問題,現寫下本篇文章,一來鞏固加深自己學習的優化技巧,二來方便正在為sql優化迷茫的猿友們提供一下思路和方法,共同進步,一起成長~ 1、現 ...
  • 很多人剛入門的時候分不清LEFT JOIN、RIGHT LOIN 和 INNER JOIN的區別,對它們的定義比較模糊,今天就簡單的介紹一下它們的區別,對於入門的人來說,應該能夠幫助你們理解。 left join(左聯接) 返回包括左表中的所有記錄和右表中聯結欄位相等的記錄 right join(右 ...
  • 進程體繫結構 -用戶進程:連接到Oracle DB的應用程式或工具 -資料庫進程 -伺服器進程:連接到Oracle實例,在用戶建立會話時啟動 -後臺進程:在啟動Oracle實例時啟動 -守護程式/應用程式進程 -網路監聽程式 -Grid infrastructe守護程式 專用伺服器,對於每個會話,運 ...
  • 本人在網上看了很多的博客資料,感覺大家都是在相互抄襲,我就自己根據自己的理解和經驗來總結一下吧; 首先觸發器的創建: 有使用Navicat的朋友可以在上面創建一個觸發器: (本人就是簡單的複製上面的sql ) CREATE TRIGGER `c_time` BEFORE INSERT ON `stu ...
  • Explain簡介 本文主要講述如何通過 explain 命令獲取 select 語句的執行計劃,通過 explain 我們可以知道以下信息:表的讀取順序,數據讀取操作的類型,哪些索引可以使用,哪些索引實際使用了,表之間的引用,每張表有多少行被優化器查詢等信息。 下麵是使用 explain 的例子: ...
  • 學習目標 -Oracle資料庫主要結構部件 -解析記憶體結構 -描述資料庫後臺進程 -邏輯存儲和物理存儲結構之間的關聯 -描述ASM存儲部件 Oracle 資料庫 -是作為一個單元處理的一組數據。 -資料庫的目的是存儲和檢索相關信息。 -Oracle關係資料庫管理系統(RDBMS)可靠地管理多用戶環境 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...