第 19.1 节:算术运算符
MySQL 提供以下算术运算符:
| 运算符 | 名称 | 示例 |
|---|---|---|
+ |
加法 | SELECT 3+5; → 8SELECT 3.5+2.5; → 6.0SELECT 3.5+2; → 5.5 |
- |
减法 | SELECT 3-5; → -2 |
* |
乘法 | SELECT 3 * 5; → 15 |
/ |
除法 | SELECT 20 / 4; → 5SELECT 355 / 113; → 3.1416SELECT 10.0 / 0; → NULL |
DIV |
整数除法 | SELECT 5 DIV 2; → 2 |
% 或 MOD |
取模 | SELECT 7 % 3; → 1SELECT 15 MOD 4; → 3SELECT 15 MOD -4; → 3SELECT -15 MOD 4; → -3SELECT -15 MOD -4; → -3SELECT 3 MOD 2.5; → 0.5 |
BIGINT
如果算术运算中的所有数字都是整数,MySQL 使用 BIGINT(有符号 64 位)整数数据类型进行计算。例如:
SELECT (1024 * 1024 * 1024 * 1024 * 1024 * 1024) + 1;
-- 结果: 1152921504606846977
如果数字超出范围,可能会发生溢出。
DOUBLE
如果算术运算中有任何数字是小数,MySQL 使用 64 位 IEEE 754 浮点运算。使用浮点运算时要小心,因为许多浮点数本质上是近似值而非精确值。
第 19.2 节:数学常量
PI
返回 π 的值,格式化为 6 位小数。实际精度为 DOUBLE:
SELECT PI(); -- 3.141593
第 19.3 节:三角函数(SIN、COS 等)
角度以弧度为单位,而非度数。所有计算均使用 IEEE 754 64 位浮点数进行。所有浮点计算都会受到微小误差(称为机器 ε 误差)的影响,因此应避免试图比较它们的相等性。使用浮点数时无法避免这些误差,这是技术本身固有的。
如果在三角函数中使用 DECIMAL 值,它们会被隐式转换为浮点数,然后再转换回 DECIMAL。
正弦
返回以弧度表示的数值 X 的正弦值:
SELECT SIN(PI()); -- 1.2246063538224e-16 (实际上接近 0)
余弦
返回以弧度表示的 X 的余弦值:
SELECT COS(PI()); -- -1
正切
返回以弧度表示的数值 X 的正切值。注意结果非常接近零,但不完全为零。这是机器 ε 误差的一个例子。
SELECT TAN(PI()); -- -1.2246063538224e-16
反余弦
如果 X 在 -1 到 1 范围内,返回 X 的反余弦值:
SELECT ACOS(1); -- 0
SELECT ACOS(1.01); -- NULL
反正弦
如果 X 在 -1 到 1 范围内,返回 X 的反正弦值:
SELECT ASIN(0.2); -- 0.20135792079033
反正切
ATAN(x) 返回单个数值的反正切值:
SELECT ATAN(2); -- 1.1071487177941
ATAN2(X, Y) 返回两个变量 X 和 Y 的反正切值。它类似于计算 Y / X 的反正切值,但在数值上更稳健:当 X 接近零时也能正确计算,并且使用两个参数的符号来确定结果的象限。
最佳实践建议尽可能使用 ATAN2() 而不是 ATAN()。
SELECT ATAN2(1, 1); -- 0.7853981633974483 (45 度)
SELECT ATAN2(1, -1); -- 2.356194490192345 (135 度)
SELECT ATAN2(0, -1); -- PI (180 度)
余切
返回 X 的余切值:
SELECT COT(12); -- -1.5726734063977
转换
SELECT RADIANS(90); -- 1.5707963267948966
SELECT SIN(RADIANS(90)); -- 1
SELECT DEGREES(1), DEGREES(PI()); -- 57.29577951308232, 180
第 19.4 节:舍入(ROUND、FLOOR、CEIL)
将小数舍入为整数值
对于精确数值(如 DECIMAL):如果数字的第一位小数为 5 或更高,此函数将向远离零的方向舍入到下一个整数。如果该小数为 4 或更低,则向零方向舍入到最接近的整数。
SELECT ROUND(4.51); -- 5
SELECT ROUND(4.49); -- 4
SELECT ROUND(-4.51); -- -5
对于近似数值(如 DOUBLE):ROUND() 函数的结果取决于 C 库;在许多系统上,这意味着 ROUND() 使用“四舍六入五成双”规则(向最近的偶数舍入):
SELECT ROUND(45e-1); -- 4 (最近的偶数是 4)
SELECT ROUND(55e-1); -- 6 (最近的偶数是 6)
向上舍入
使用 CEIL() 或 CEILING() 函数:
SELECT CEIL(1.23); -- 2
SELECT CEILING(4.83); -- 5
向下舍入
使用 FLOOR() 函数:
SELECT FLOOR(1.99); -- 1
FLOOR 和 CEIL 分别向负无穷小方向或正无穷大方向舍入:
SELECT FLOOR(-1.01), CEIL(-1.01); -- -2, -1
SELECT FLOOR(-1.99), CEIL(-1.99); -- -2, -1
舍入到指定小数位数
SELECT ROUND(1234.987, 2); -- 1234.99
SELECT ROUND(1234.987, -2); -- 1200
关于向上/向下以及“5”的讨论同样适用。
第 19.5 节:乘方(POW)
使用 POW() 或 POWER() 函数计算 x 的 y 次方:
SELECT POW(2, 2); -- 4
SELECT POW(4, 2); -- 16
第 19.6 节:平方根(SQRT)
使用 SQRT() 函数。如果数字为负数,返回 NULL:
SELECT SQRT(16); -- 4
SELECT SQRT(-3); -- NULL
第 19.7 节:随机数(RAND)
生成随机数
使用 RAND() 函数生成 0 到 1 之间的伪随机浮点数:
SELECT i, RAND() FROM t;
结果类似:
| i | RAND() |
|---|---|
| 1 | 0.6191438870682 |
| 2 | 0.93845168309142 |
| 3 | 0.83482678498591 |
范围内的随机数
要生成范围 a ≤ n ≤ b 内的随机数,可以使用以下公式:
FLOOR(a + RAND() * (b - a + 1))
例如,生成 7 到 12 之间的随机数:
SELECT FLOOR(7 + (RAND() * 6));
随机返回表中的行:
SELECT * FROM tbl ORDER BY RAND();
这些是伪随机数。
MySQL 中的伪随机数生成器在密码学上不安全。也就是说,如果你使用 MySQL 生成用作秘密的随机数,一个知道你使用 MySQL 的坚定攻击者将能够比你想象的更容易地猜测你的秘密。
第 19.8 节:绝对值和符号(ABS、SIGN)
返回数字的绝对值:
SELECT ABS(2); -- 2
SELECT ABS(-46); -- 46
数字的符号将其与 0 进行比较:
| 符号结果 | 说明 | 示例 |
|---|---|---|
| -1 | n < 0 | SELECT SIGN(-3); → -1 |
| 0 | n = 0 | SELECT SIGN(0); → 0 |
| 1 | n > 0 | SELECT SIGN(42); → 1 |