算术运算符
导学
SQL 不仅是查询语言,也具备计算能力。算术运算符让你在查询中直接完成加减乘除、取模等运算,无需将数据拉回程序层再处理。
定义
算术运算符:用于对数值型数据进行数学运算的符号。MySQL 支持 +(加)、-(减)、*(乘)、/(除)、DIV(整除)、% 或 MOD(取模)。
运算符一览
| 运算符 | 含义 | 示例 | 结果 |
|---|---|---|---|
+ | 加法 | SELECT 10 + 3 | 13 |
- | 减法 | SELECT 10 - 3 | 7 |
* | 乘法 | SELECT 10 * 3 | 30 |
/ | 除法 | SELECT 10 / 3 | 3.3333 |
DIV | 整数除法 | SELECT 10 DIV 3 | 3 |
% / MOD | 取模 | SELECT 10 % 3 | 1 |
演示数据准备
DROP TABLE IF EXISTS employees;
CREATE TABLE employees (
emp_id INT PRIMARY KEY AUTO_INCREMENT,
emp_name VARCHAR(20),
dept VARCHAR(20),
score DECIMAL(5,2)
);
INSERT INTO employees (emp_name, dept, score) VALUES
('大翔', '技术部', 100),
('白歌', '技术部', NULL);
当前 employees 表中的完整数据如下:
| emp_id | emp_name | dept | score |
|---|---|---|---|
| 1 | 大翔 | 技术部 | 100 |
| 2 | 白歌 | 技术部 | NULL |
SQL 示例
场景一:查询中的计算列(加减乘除)
当前数据状态:见上文 employees 表完整数据。
执行语句:
SELECT
emp_name,
score,
score + 10 AS plus_10,
score - 10 AS minus_10,
score * 2 AS doubled,
score / 2 AS halved
FROM employees;
操作后结果:
| emp_name | score | plus_10 | minus_10 | doubled | halved |
|---|---|---|---|---|---|
| 大翔 | 100 | 110 | 90 | 200 | 50.0000 |
| 白歌 | NULL | NULL | NULL | NULL | NULL |
结果解读:score + 10、score - 10、score * 2、score / 2 分别演示了加、减、乘、除四种运算。注意白歌的 score 为 NULL,因此所有计算结果均为 NULL(任何包含 NULL 的算术运算结果都是 NULL)。
场景二:整数除法的陷阱
当前数据状态:无需表数据,直接演示常量运算。
执行语句:
SELECT 10 / 3; -- 结果:3.3333(浮点数除法)
SELECT 10 DIV 3; -- 结果:3(整数除法,截断小数)
SELECT 10 / 4; -- 结果:2.5000
SELECT 10 DIV 4; -- 结果:2
SELECT -10 DIV 3; -- 结果:-3
操作后结果:
| 10 / 3 | 10 DIV 3 | 10 / 4 | 10 DIV 4 | -10 DIV 3 |
|---|---|---|---|---|
| 3.3333 | 3 | 2.5000 | 2 | -3 |
结果解读:MySQL 中 / 总是返回浮点数结果,即使两个操作数都是整数。如需整数除法,用 DIV,它会截断小数部分(向零取整)。
场景三:取模运算的应用
当前数据状态:见上文 employees 表完整数据。
执行语句(判断奇偶):
SELECT emp_name, emp_id FROM employees WHERE emp_id % 2 = 0;
-- 等价于
-- SELECT emp_name, emp_id FROM employees WHERE MOD(emp_id, 2) = 0;
操作后结果:
| emp_name | emp_id |
|---|---|
| 白歌 | 2 |
结果解读:% 或 MOD 返回除法的余数。emp_id % 2 = 0 筛选出偶数 ID 的员工。
再看一个分批场景:
SELECT
emp_id,
emp_name,
CASE WHEN emp_id % 3 = 1 THEN '第一批'
WHEN emp_id % 3 = 2 THEN '第二批'
ELSE '第三批' END AS batch
FROM employees;
操作后结果:
| emp_id | emp_name | batch |
|---|---|---|
| 1 | 大翔 | 第一批 |
| 2 | 白歌 | 第二批 |
结果解读:利用 emp_id % 2 将员工按奇偶分到不同批次中。
场景四:NULL 参与的运算
当前数据状态:见上文 employees 表完整数据。
执行语句:
SELECT
emp_name,
score,
score + NULL AS add_null,
score * NULL AS mul_null
FROM employees;
操作后结果:
| emp_name | score | add_null | mul_null |
|---|---|---|---|
| 大翔 | 100 | NULL | NULL |
| 白歌 | NULL | NULL | NULL |
结果解读:任何算术运算中只要有一个操作数是 NULL,结果就是 NULL。白歌的 score 为 NULL,因此计算结果均为 NULL。其他员工与 NULL 常量运算,结果同样为 NULL。
在计算列时,应使用 IFNULL() 函数处理:
SELECT
emp_name,
score,
IFNULL(score, 0) AS safe_score,
IFNULL(score, 0) + 10 AS total_safe
FROM employees;
操作后结果:
| emp_name | score | safe_score | total_safe |
|---|---|---|---|
| 大翔 | 100 | 100 | 110 |
| 白歌 | NULL | 0 | 10 |
结果解读:IFNULL(score, 0) 将 NULL 替换为 0,因此白歌的 total_safe 正确计算为 10。
场景五:除零的处理
当前数据状态:无需表数据,直接演示常量运算。
执行语句:
SELECT 10 / 0; -- 结果:NULL
SELECT 10 DIV 0; -- 结果:NULL
SELECT 10 % 0; -- 结果:NULL
操作后结果:
| 10 / 0 | 10 DIV 0 | 10 % 0 |
|---|---|---|
| NULL | NULL | NULL |
结果解读:MySQL 中除以零返回 NULL 而非报错。这在某些场景下会导致难以发现的逻辑错误。如需报错,可在 SQL Mode 中启用 ERROR_FOR_DIVISION_BY_ZERO。
验证 SQL Mode:
-- 查看当前 SQL Mode
SELECT @@sql_mode;
-- 启用严格模式(含除零报错)
SET sql_mode = 'STRICT_ALL_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ZERO_IN_DATE,NO_ZERO_DATE';
运算符优先级
算术运算符优先级与数学一致:
*,/,DIV,%,MOD+,-- 同优先级从左到右计算
执行语句:
SELECT 10 + 2 * 3; -- 结果:16(先乘后加)
SELECT (10 + 2) * 3; -- 结果:36(括号优先)
SELECT 100 / 10 * 2; -- 结果:20(同优先级从左到右)
SELECT 100 / (10 * 2); -- 结果:5(括号优先)
操作后结果:
| 10 + 2 * 3 | (10 + 2) * 3 | 100 / 10 * 2 | 100 / (10 * 2) |
|---|---|---|---|
| 16 | 36 | 20.0000 | 5.0000 |
结果解读:10 + 2 * 3 先算 2 * 3 = 6,再算 10 + 6 = 16。括号可以强制改变优先级。同优先级(/ 和 *)时从左到右计算,因此 100 / 10 * 2 = 10 * 2 = 20。
常见误区
| 误区 | 正解 |
|---|---|
10 / 3 结果是 3 | / 返回浮点数,结果是 3.3333。整数除法用 DIV。 |
| 除以零会报错 | MySQL 返回 NULL,不会报错。 |
| 字符串参与算术运算会报错 | MySQL 会尝试将字符串隐式转为数字,转换失败则视为 0。 |
| NULL 参与运算会报错 | NULL 参与运算结果恒为 NULL,不会报错。 |
面试考点
Q:MySQL 中 10 / 3 和 10 DIV 3 的区别?
/是浮点除法,返回3.3333;DIV是整数除法,返回3(截断小数)。
Q:算术运算中遇到 NULL 会怎样?
任何包含 NULL 的算术运算结果都是 NULL。应使用
IFNULL(column, 0)或COALESCE(column, 0)将 NULL 转为默认值后再计算。
Q:如何在查询中实现"四舍五入保留两位小数"?
使用
ROUND(score / 2, 2)。ROUND是数值函数,详见第03章《数值函数》文档。
Q:MySQL 中除以零会怎样?
默认返回 NULL。如果 SQL Mode 启用了
ERROR_FOR_DIVISION_BY_ZERO,则会报错。
小结
- 算术运算符在
SELECT中直接计算,减少程序层处理 /是浮点除法,DIV是整数除法- NULL 参与的运算结果恒为 NULL
- 除零在 MySQL 中返回 NULL 而非报错,需特别注意
- 使用
IFNULL或COALESCE处理 NULL 值,避免计算结果全为 NULL
下一章引子:算术运算符处理数字,但数据库中有一种特殊的"值"——NULL,它不参与普通运算,需要专门的处理方式。