完全掌握 MySQL MAX 函數!最大值取得與實用用法

目次

1. 簡介

MySQL 是全球廣泛使用的資料庫管理系統。其中,MAX 函數 是資料分析或報告製作時經常使用的關鍵彙總函數。透過使用此函數,可以輕鬆取得指定欄位的最大值。

本文將從 MySQL 的 MAX 函數基本用法,到應用範例、注意事項,一一清楚說明。旨在提供對初學者到中級者皆有幫助的內容,請務必參考。

2. MAX 函數的基本用法

MAX 函數可用於數值、日期、字串等各種資料類型。本節將詳細說明基本用法。

MAX 函數的語法

以下是 MAX 函數的基本語法。

SELECT MAX(column_name) FROM table_name;

使用此語法,可以取得指定欄位的最大值。

數值欄位的使用範例

從員工薪資資料表中,取得最高薪資的範例。

SELECT MAX(salary) FROM employees;

輸出範例:

MAX(salary)
120000

此結果顯示,salary 欄位中的最大值為 120000

日期欄位的使用範例

若要取得員工最新的聘僱日期,請如下所述。

SELECT MAX(hire_date) FROM employees;

輸出範例:

MAX(hire_date)
2025-01-01

從此結果可知,最新聘僱日期為 2025-01-01

字串欄位的使用範例

字串欄位也可以使用 MAX 函數。對於字串,會依字典順序返回最晚的位置值。

SELECT MAX(last_name) FROM employees;

輸出範例:

MAX(last_name)
Yamamoto

此結果顯示,按字母順序或五十音順序,最後的位置名稱為 Yamamoto

3. 條件式下的最大值取得

MAX 函數也可以條件式使用。本節將說明條件式取得最大值的方法。

與 WHERE 子句的組合

要指定特定條件來取得最大值,請使用 WHERE 子句。

例:取得部署 ID 為 10 的員工中最高的薪資

SELECT MAX(salary) FROM employees WHERE department_id = 10;

輸出範例:

MAX(salary)
90000

此查詢從部署 ID 為 10 的員工中取得最大薪資。

實務中的應用範例

要取得特定專案相關的最大費用時,也使用相同的語法。

SELECT MAX(cost) FROM projects WHERE project_status = 'active';

此查詢取得 active 專案中的最大成本。

4. 取得各群組最大值的方法

使用 MySQL 的 GROUP BY 子句,可以取得特定群組的最大值。例如,部門最高的薪資或每月最高銷售額等,在將資料群組化進行分析時非常方便。本節將詳細說明取得群組最大值的方法。

基本語法

要取得群組的最大值,請如下所述寫入。

SELECT 群組化欄位, MAX(目標欄位)
FROM 資料表名稱
GROUP BY 群組化欄位;

使用此語法,可以以指定的欄位為基準群組化資料,並取得各群組內的最大值。

使用範例:取得部門最高薪資

以下是從員工資料表取得 部門最高薪資 的查詢。

SELECT department_id, MAX(salary)
FROM employees
GROUP BY department_id;

輸出範例:

department_idMAX(salary)
1120000
290000
380000

此結果顯示每個部門(department_id)的最大薪資(MAX(salary))。

使用範例:取得每月最大銷售額

從銷售資料表取得各月最大銷售額時,請如下所述寫入。

SELECT DATE_FORMAT(sale_date, '%Y-%m') AS sale_month, MAX(amount)
FROM sales
GROUP BY sale_month;

輸出範例:

sale_monthMAX(amount)
2025-0150000
2025-0270000
2025-0360000

此查詢將 sale_date 欄位的日期格式化為年月(%Y-%m),並取得每月最大銷售額。

使用 GROUP BY 時的注意事項

  1. SELECT 語句包含欄位的限制
    使用 GROUP BY 子句時,SELECT 語句包含的欄位必須是以下任一:
  • GROUP BY 子句指定的欄位
  • 彙總函數(例如:MAX、SUM、COUNT 等) 例如:以下查詢會發生錯誤。
   SELECT department_id, salary
   FROM employees
   GROUP BY department_id;

原因:salary 未包含在彙總函數或 GROUP BY 子句中。

  1. NULL 值的處理
    如果群組化目標的欄位包含 NULL 值,NULL 值會被視為另一個群組處理。 例如:部署 ID 為 NULL 的資料也會作為一個群組計算。
  2. 效能最佳化
    在群組化大量資料時,利用索引可以提升查詢效能。請視需要設定索引。

5. 取得最大值的整個記錄的方法

使用 MySQL 的 MAX 函數,可以取得特定欄位的最大值,但僅此而已無法取得持有最大值的整個記錄。在實際的資料分析或應用程式中,不僅需要最大值,還經常需要相關的其他欄位資訊。

本節將詳細說明取得持有最大值的整個記錄的方法。

方法 1: 使用子查詢

利用子查詢,可以取得特定欄位最大值的記錄。

範例: 取得最高薪資員工的資訊

SELECT *
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);

輸出範例:

employee_idnamesalarydepartment_id
101Tanaka1200001

此查詢的運作機制:

  1. 子查詢 (SELECT MAX(salary) FROM employees) 取得最高薪資。
  2. 外層查詢取得持有該最高薪資的整個記錄。

方法 2: 使用 JOIN

使用 JOIN 可以建立更靈活的查詢。

範例: 取得每個部門最高薪資員工的資訊

SELECT e.*
FROM employees e
JOIN (
    SELECT department_id, MAX(salary) AS max_salary
    FROM employees
    GROUP BY department_id
) subquery
ON e.department_id = subquery.department_id AND e.salary = subquery.max_salary;

輸出範例:

employee_idnamesalarydepartment_id
101Tanaka1200001
202Suzuki900002

此查詢的運作機制:

  1. 子查詢計算每個部門的最高薪資。
  2. 主查詢取得持有該最大薪資的員工整個記錄。

方法 3: 使用視窗函數(MySQL 8.0 以降)

MySQL 8.0 以降可以使用視窗函數,以更簡潔且高效的方式取得最大值的記錄。

範例: 取得每個部門最高薪資的員工

SELECT employee_id, name, salary, department_id
FROM (
    SELECT *,
           RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rnk
    FROM employees
) ranked
WHERE rnk = 1;

輸出範例:

employee_idnamesalarydepartment_id
101Tanaka1200001
202Suzuki900002

此查詢的運作機制:

  1. RANK() 函數根據薪資降序為每個部門內的記錄賦予排名。
  2. 外層查詢抽出排名為 1 的記錄(持有最大值的記錄)。

注意事項

  1. 多個記錄持有最大值的情況
  • 若最大值在多個記錄中重複,無論使用哪種方法,都會取得所有符合的記錄。範例:
   SELECT *
   FROM employees
   WHERE salary = (SELECT MAX(salary) FROM employees);

輸出範例:

employee_idnamesalarydepartment_id
101Tanaka1200001
102Sato1200001
  1. 效能最佳化
  • 對大型資料集使用子查詢或 JOIN 可能導致效能降低。
  • 適當設定索引可以提升查詢執行速度。

實務應用範例

  1. 從商品表格取得最高價格的商品
   SELECT *
   FROM products
   WHERE price = (SELECT MAX(price) FROM products);
  1. 取得每個專案的最大成本細節
   SELECT p.*
   FROM projects p
   JOIN (
       SELECT project_id, MAX(cost) AS max_cost
       FROM project_costs
       GROUP BY project_id
   ) subquery
   ON p.project_id = subquery.project_id AND p.cost = subquery.max_cost;

6. 使用 MAX 函數時的注意事項

MySQL 的MAX 函數是一個非常方便的聚合函數,但是在使用時有一些注意點。透過了解資料的特性、效能,以及 NULL 值的處理,即可防止錯誤的結果或效能降低。本節將詳細說明使用 MAX 函數時應注意的要點。

NULL 值的處理

MySQL 中,NULL 值被視為「未知的值」。因此,使用 MAX 函數時,NULL 值會被忽略。

範例:取得包含 NULL 值的資料的最大值

SELECT MAX(salary) FROM employees;

資料:

employee_idnamesalary
1Tanaka50000
2SatoNULL
3Suzuki60000

輸出:

MAX(salary)
60000

要點:

  • 即使 salary 欄位包含 NULL 值,MAX 函數仍會忽略 NULL 值進行計算。
  • 包含 NULL 值時,需要注意精確的處理。

存在多個最大值的情況

MAX 函數會返回單一的最大值,但資料集中可能存在多個記錄具有相同的最大值。在這種情況下,為了取得所有具有最大值的記錄,需要像以下這樣巧妙地設計查詢。

範例:取得具有多個最大值的員工

SELECT * 
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);

資料:

employee_idnamesalary
1Tanaka60000
2Sato60000
3Suzuki50000

輸出:

employee_idnamesalary
1Tanaka60000
2Sato60000

要點:

  • 由於單獨的 MAX 函數可能無法應對,因此需要使用子查詢來取得所有記錄的方法。

對效能的影響

如果查詢簡單,MAX 函數會高速運作,但處理大量資料或複雜查詢時,可能會導致效能降低。

提升效能的提示

  1. 活用索引
    透過在使用的 MAX 函數欄位設定索引,即可大幅改善查詢速度。
   CREATE INDEX idx_salary ON employees(salary);
  1. 排除不必要的資料
    使用 WHERE 子句來縮小目標資料,即可減少處理的資料量。
   SELECT MAX(salary)
   FROM employees
   WHERE department_id = 1;
  1. 分割計算
    考慮將多個子集分開計算最大值,並取得最終最大值的方法。

其他考量事項

  1. 資料型別的影響
    MAX 函數的行為會因欄位的資料型別而異。
  • 數值:簡單的大小比較。
  • 字串:依字典順比較。
  • 日期:返回時間上最晚的值。 範例:
   SELECT MAX(last_name) FROM employees;

在這種情況下,會返回字串字典順的最大值。

  1. 除 NULL 外的缺失資料
    如果資料缺失,計算結果可能不符合預期。需要進行資料清理。
  2. 與其他聚合函數的組合
    將 MAX 函數與其他聚合函數(SUM、AVG 等)組合使用時,需要注意正確解釋結果。

7. FAQ:常見問題

MySQL 的 MAX 函數相關,常見的疑問彙整並加以說明。本 FAQ 區段將涵蓋從基本問題到進階內容。

Q1: MAX 函數可以同時用於多個欄位嗎?

A1:否,MAX 函數是用於單一欄位。如果要取得多個欄位的最大值,則需要分別對每個欄位套用 MAX 函數。

範例:個別取得多個欄位的最大值

SELECT MAX(salary) AS max_salary, MAX(bonus) AS max_bonus
FROM employees;

Q2: 對字串欄位使用 MAX 函數的結果如何?

A2:將 MAX 函數套用於字串欄位時,將依字典順序返回最大值。

範例:取得字串的最大值

SELECT MAX(last_name) FROM employees;

重點:

  • 在字典順序中,「Z」位於「A」之後,數字和符號也會被評估。
  • 如果包含特殊字元,結果可能會出現非預期的順序。

Q3: MAX 函數與 ORDER BY 子句的差異是什麼?

A3:MAX 函數與 ORDER BY 子句雖然常被用於類似目的,但其行為不同。

  • MAX 函數: 直接取得指定欄位的最大值。
  • ORDER BY 子句: 依指定欄位排序資料,並視需要取得最初或最後的值。

範例:使用 ORDER BY 子句取得最大值

SELECT * FROM employees
ORDER BY salary DESC
LIMIT 1;

重點:

  • MAX 函數在效能上通常較優異。
  • ORDER BY 子句適合用於同時取得最大值及其相關資訊的記錄。

Q4: 包含 NULL 值時,MAX 函數是否能正確運作?

A4:是,MAX 函數會忽略 NULL 值。因此,即使包含 NULL 值,也不會影響最大值的計算。

範例:包含 NULL 值時的運作

SELECT MAX(salary) FROM employees;

資料:

employee_idnamesalary
1Tanaka60000
2SatoNULL
3Suzuki50000

結果:

MAX(salary)
60000

注意事項:如果想將 NULL 值也納入處理範圍,可以使用 IFNULL 函數將 NULL 取代為預設值。

SELECT MAX(IFNULL(salary, 0)) FROM employees;

Q5: 使用 MAX 函數時,有什麼方法可以提升效能?

A5:請考慮以下方法:

  1. 索引設定: 為使用 MAX 函數的欄位設定索引,可大幅提升查詢速度。
   CREATE INDEX idx_salary ON employees(salary);
  1. 資料範圍縮小: 使用 WHERE 子句指定條件,以減少目標資料。
   SELECT MAX(salary) FROM employees WHERE department_id = 1;
  1. 查詢最佳化: 排除不必要的計算,並維持簡單的查詢結構。

Q6: 結合 MAX 函數與 GROUP BY 子句時,會得到什麼結果?

A6:結合 GROUP BY 子句與 MAX 函數,即可取得各群組的最大值。

範例:取得各部門的最高薪資

SELECT department_id, MAX(salary)
FROM employees
GROUP BY department_id;

結果:

department_idMAX(salary)
1120000
290000

Q7: 若存在多筆具有最大值的記錄,如何取得全部?

A7:使用子查詢或 JOIN,即可取得多筆具有最大值的記錄。

範例:取得所有最大值記錄

SELECT *
FROM employees
WHERE salary = (SELECT MAX(salary) FROM employees);

Q8: MAX 函數可以與視窗函數併用嗎?

A8:是,從 MySQL 8.0 開始,即可與視窗函數併用,實現更靈活的查詢。

範例:取得各部門最高薪資的員工

SELECT employee_id, name, salary, department_id
FROM (
    SELECT *,
           RANK() OVER (PARTITION BY department_id ORDER BY salary DESC) AS rnk
    FROM employees
) ranked
WHERE rnk = 1;

8. 總結

MySQL 的 MAX 函數是資料庫操作和資料分析中非常強大的工具。本文從 MAX 函數的基本用法,到條件式、群組化、取得最大值記錄的方法,以及效能最佳化,全面性地說明了。

主要要點

  1. MAX 函數的基本用法
    MAX 函數用來取得指定欄位的最大值。支援數值、字串、日期等各種資料型別。
  2. 條件式最大值的取得
    使用 WHERE 子句,可以取得符合特定條件的最大值。在求取專案或部門的最大值時很方便。
  3. 群組別最大值的取得
    使用 GROUP BY 子句取得每個群組的最大值的方法,也詳細說明了。可用於部門別薪資或每月銷售額等。
  4. 取得最大值的整個記錄
    使用子查詢、JOIN、視窗函數,學習了有效率地取得最大值記錄整體的方法。
  5. 使用 MAX 函數時的注意事項
    NULL 值的處理或存在多個最大值的情況,考慮效能影響很重要。
  6. FAQ
    作為常見問題,提供 MAX 函數在多個欄位使用的方法及效能最佳化的提示。

最後

適當活用 MAX 函數,可以使資料分析和報告製作更有效率。繼續學習 SQL,並實踐以建立更進階的查詢。

希望本文能幫助加深對使用 MySQL 進行資料操作和分析的理解。