使用 COUNT() 與 AVG() 在資料庫層直接計算統計值
一、為什麼要在 SQL 層做統計?
在之前,所有統計(例如平均年齡)都是在 Java 端 用 for 迴圈手動加總再除以總數。
但這樣會有幾個問題:
每次都要把所有資料「讀進記憶體」再計算,這樣效能差尤其是資料多時,而且無法快速產出更複雜的統計所以更聰明的做法是讓資料庫自己幫我算。
二、SQL 統計函式介紹
SQL 提供許多「聚合函式 (Aggregate Functions)」,
讓我直接在查詢階段統計整張表或部分資料。
函式 功能 範例
COUNT() 計算筆數 COUNT(*) 或 COUNT(column)
AVG() 計算平均值 AVG(age)
SUM() 計算總和 SUM(age)
MAX() 取最大值 MAX(age)
MIN() 取最小值 MIN(age)
三、在你的學生資料表中可以這樣用
需求 SQL 指令 回傳結果
總學生數 SELECT COUNT(*) FROM students; 整數
平均年齡 SELECT AVG(age) FROM students; 浮點數
最年長學生 SELECT MAX(age) FROM students; 整數
最年輕學生 SELECT MIN(age) FROM students; 整數
四、為什麼要在 SQL 層做,而不是 Java 層?
項目 在 Java 計算 在 SQL 計算
速度 先讀全部資料再算 由資料庫引擎直接計算(更快)
記憶體 要把全部資料載入 ArrayList 不需要載入整張表
準確性 容易出現浮點誤差 SQL 內建高精度統計
維護性 要寫多行程式碼 一行 SQL 就完成
因此在真實系統裡,「統計功能都應該交給資料庫」(例如 COUNT, AVG, SUM 全部在 SQL 執行)。
五、這和你的 SqliteStudentRepository 的關係
這兩個方法正好對應 SQL 的 COUNT() 和 AVG():
Repository 方法 對應 SQL 功能
countStudents() SELECT COUNT(*) FROM students; 回傳學生總數
averageAge() SELECT AVG(age) FROM students; 回傳平均年齡
StudentManager 會呼叫這兩個方法,
讓資料庫直接處理統計,再把結果回傳給 CLI 顯示。
六、Data Flow
Main → StudentManager → SqliteStudentRepository → SQL 執行
七、學習重點整理
COUNT() 用來計算資料筆數
AVG() 用來計算平均值
聚合函式 (Aggregate Function) 直接讓 SQL 幫忙運算,效能更高
ResultSet Java 端接收查詢結果的介面
分層設計 統計邏輯放在 Repository,不放在 Manager
hands-on practice的部分: