首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server 2008 聚合函數實戰教學:SUM、COUNT、AVG、MAX、MIN、GROUP BY、DISTINCT 完整範例

     編輯:關於SqlServer

前言

聚合函數是資料分析的基石。本文以 tb_Students (學生) 與 tb_Class (班級) 兩張範例表,完整演示五大基本聚合函數、分組聚合、去重聚合與實戰查詢模式。

一、範例資料準備


-- 學生表
CREATE TABLE tb_Students (
    id INT IDENTITY PRIMARY KEY,
    name NVARCHAR(16) NOT NULL,
    age INT NOT NULL
);
INSERT INTO tb_Students (name, age) VALUES 
(N'tiana', 15), (N'yardi', 20), (N'zhangyun', 18);

-- 班級表
CREATE TABLE tb_Class (
    classid INT IDENTITY PRIMARY KEY,
    classname NVARCHAR(16) NOT NULL,
    students INT NOT NULL,
    teacher NVARCHAR(16) NOT NULL
);
INSERT INTO tb_Class (classname, students, teacher) VALUES
(N'1班', 25, N'yl'), (N'2班', 18, N'wsp'), (N'3班', 24, N'yl'),
(N'4班', 25, N'zhy'), (N'5班', 22, N'wsp'), (N'6班', 25, N'yl'),
(N'7班', 20, N'zhy'), (N'8班', 22, N'wsp');

二、五大基本聚合函數

函數用途查詢範例 (學生年齡 > 15)結果
SUM加總SELECT SUM(age) FROM tb_Students WHERE age > 15;38 (20+18)
COUNT計數SELECT COUNT(*) FROM tb_Students WHERE age > 15;2
AVG平均SELECT AVG(age) FROM tb_Students WHERE age > 15;19
MAX最大值SELECT MAX(age) FROM tb_Students WHERE age > 15;20
MIN最小值SELECT MIN(age) FROM tb_Students WHERE age > 15;18
COUNT 細節:COUNT(*) 計算列數 (含 NULL);COUNT(col) 計算非 NULL 個數;COUNT(DISTINCT col) 計算非 NULL 去重個數。本例三欄位無 NULL,結果一致。

三、GROUP BY 分組聚合


-- 依教師分組,計算各教師班級學生數統計
SELECT 
    teacher,
    SUM(students) AS TotalStudents,
    COUNT(*) AS ClassCount,
    AVG(students * 1.0) AS AvgClassSize,
    MAX(students) AS MaxClassSize,
    MIN(students) AS MinClassSize
FROM tb_Class
GROUP BY teacher;

結果


teacher  TotalStudents  ClassCount  AvgClassSize  MaxClassSize  MinClassSize
yl       74             3           24.666...     25            24
wsp      62             3           20.666...     25            18
zhy      45             2           22.5          25            20

四、DISTINCT 去重聚合


-- 查詢有多少位不同的教師
SELECT COUNT(DISTINCT teacher) FROM tb_Class;
-- 結果: 3 (yl, wsp, zhy)
  • DISTINCT 放在聚合函數**括號內**,先去重再聚合。
  • 可用於 SUM(DISTINCT col)、AVG(DISTINCT col) 等,但極少用於業務邏輯 (意義模糊)。

五、進階實戰模式

5.1 HAVING 篩選分組結果


-- 找出總學生數超過 60 人的教師
SELECT teacher, SUM(students) AS Total
FROM tb_Class
GROUP BY teacher
HAVING SUM(students) > 60;
WHERE vs HAVING:WHERE 篩選**原始列** (聚合前);HAVING 篩選**分組彙總結果** (聚合後)。

5.2 多欄位分組 + ROLLUP 小計


SELECT 
    teacher,
    classname,
    SUM(students) AS Total
FROM tb_Class
GROUP BY ROLLUP (teacher, classname);
-- 產生:各班級小計 → 各教師小計 → 總計

5.3 聚合函數忽略 NULL

  • SUM/AVG/MIN/MAX 自動忽略 NULL 值。
  • COUNT(col) 忽略 NULL;COUNT(*) 不忽略。

5.4 條件聚合 (CASE 結合聚合)


SELECT 
    teacher,
    SUM(CASE WHEN classname LIKE '1%' THEN students ELSE 0 END) AS Class1_Sum,
    SUM(CASE WHEN students >= 25 THEN 1 ELSE 0 END) AS LargeClassCount
FROM tb_Class
GROUP BY teacher;

六、常見錯誤與避坑

錯誤原因修正
SELECT name, SUM(age) FROM tb_Students非聚合欄位 name 未出現在 GROUP BY加入 GROUP BY name 或移除 name
SELECT AVG(SUM(age)) ...**不可巢狀聚合函數**用子查詢/CTE 分層:SELECT AVG(Total) FROM (SELECT SUM(age) AS Total FROM ... GROUP BY ...) t
WHERE SUM(age) > 100WHERE 不可用聚合函數改用 HAVING SUM(age) > 100
整數除法導致 AVG 截斷AVG(INT) 回傳 INTAVG(age * 1.0) 或 CAST(AVG(age * 1.0) AS DECIMAL(10,2))

七、效能提示

  1. 聚合欄位**建立索引** (含分組欄位) 可用 Stream Aggregate 避免 Sort。
  2. 大表分組聚合考慮 **Columnstore Index** (SQL 2012+),批次模式處理極快。
  3. 避免 DISTINCT 濫用;若業務允許,改用 GROUP BY 更可控。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved