Skip to content

sql-min-and-max

聚合函数(Aggregate functions)对一组行执行计算并返回一个单一的、汇总的值。它们对于数据分析和报表至关重要。最常见的聚合函数包括:

  • COUNT():计算行数。
  • SUM():计算列中值的总和。
  • AVG():计算列中值的平均值。
  • MAX():返回集合中的最大值。
  • MIN():返回集合中的最小值。

在本教程中,我们将重点介绍 MAX() 和 MIN()。

在我们的示例中,我们将使用一个 Employees 表。

CREATE TABLE Employees (
employee_id SERIAL PRIMARY KEY,
first_name VARCHAR(50),
last_name VARCHAR(50),
department VARCHAR(50),
hire_date DATE,
salary NUMERIC(10, 2)
);
INSERT INTO Employees (first_name, last_name, department, hire_date, salary) VALUES
('Alice', 'Smith', 'Engineering', '2020-03-15', 90000.00),
('Bob', 'Johnson', 'Engineering', '2019-07-22', 115000.00),
('Charlie', 'Brown', 'Marketing', '2021-01-10', 72000.00),
('Diana', 'Prince', 'Marketing', '2022-06-01', 80000.00),
('Ethan', 'Hunt', 'Operations', '2018-11-05', 105000.00);

MAX() 函数返回指定列中的最大值。

要查找所有员工中的最高工资:

SELECT MAX(salary) AS highest_salary
FROM Employees;

此查询将返回一个单行单列,值为 115000.00。

当 MAX() 与 GROUP BY 子句结合使用时,它变得更加强大,可以查找不同组内的最大值。例如,要查找每个部门的最高工资:

SELECT department, MAX(salary) AS highest_salary_in_dept
FROM Employees
GROUP BY department;

这将产生:

departmenthighest_salary_in_dept
Engineering115000.00
Marketing80000.00
Operations105000.00

通常,你不仅想要最大值,还想要与该值关联的整行数据。实现这一目标的常见方法是在子查询中使用 MAX()。

SELECT first_name, last_name, salary
FROM Employees
WHERE salary = (SELECT MAX(salary) FROM Employees);

对于复杂查询,一种更现代且通常更具可读性的方法是使用通用表表达式(Common Table Expression, CTE)。

WITH MaxSalary AS (
SELECT MAX(salary) AS max_sal FROM Employees
)
SELECT e.first_name, e.last_name, e.salary
FROM Employees e, MaxSalary ms
WHERE e.salary = ms.max_sal;

MIN() 函数是 MAX() 的对应函数,它返回指定列中的最小值。

要查找所有员工中的最低工资:

SELECT MIN(salary) AS lowest_salary
FROM Employees;

结果:72000.00

MIN() 和 MAX() 不仅适用于数字。它们还可以用于字符串(按字母顺序)和日期(按时间顺序)。

查找最早的入职日期(“最小值”日期):

SELECT MIN(hire_date) AS first_hire_date
FROM Employees;

结果:2018-11-05

按字母顺序查找第一个名字:

SELECT MIN(first_name) AS first_alphabetically
FROM Employees;

结果:Alice

对于非常大的表,查找最小值或最大值可能需要全表扫描,这会很慢。如果你经常查询某个特定列的 MIN() 或 MAX(),在该列上创建索引可以显著提高性能。数据库之后可以直接查看索引中的第一个或最后一个条目,而无需扫描每一行。

我们来回答一些业务问题:

问题:哪个部门的员工入职日期最新?

SELECT department
FROM Employees
WHERE hire_date = (SELECT MAX(hire_date) FROM Employees);

结果:Marketing

问题:工程部门的工资范围(最低和最高工资)是多少?

SELECT
MIN(salary) AS min_eng_salary,
MAX(salary) AS max_eng_salary
FROM Employees
WHERE department = 'Engineering';

结果:90000.00, 115000.00