Skip to content

数字函数


在数据库开发中,经常需要处理数值的正负问题,例如取绝对值进行计算或比较。这时候就可以使用 ABS(Absolute Value,绝对值)函数

ABS(number); --`number`:可以是整数、浮点数或表达式。
  • 例子:
SELECT ABS(-3.5); -- 3.5
  • 场景:误差值、偏差度量取正。

在数据库数值计算中,有时我们并不关心数值的大小,而是关心它的“正、负、零”状态,这时就可以使用 SIGN 函数

SIGN(number);
  • 参数

    • number:可以是整数、浮点数或表达式。
  • 返回值

    • number > 0,返回 1

    • number = 0,返回 0

    • number < 0,返回 -1

  • 例子:

SELECT SIGN(-10), SIGN(0), SIGN(8); -- -1, 0, 1
  • 场景:快速判断增长/下降/持平。

在数据库运算中,如果需要把一个小数向上取整为最小的整数,可以使用 CEILCEILING 函数。两者在不同数据库中可能存在命名差异,但功能相同。

CEIL(x) -- 同义:CEILING(x)
  • 参数

    • number:可以是整数、浮点数或表达式。
  • 返回值

    • 返回 大于或等于该数值的最小整数
  • 例子:

SELECT CEIL(3.01), CEIL(-3.01); -- 4, -3
  • 场景:分页页数、箱体/分组上取整。

在数据库运算中,如果需要把一个小数向下取整为最大的整数,可以使用 FLOOR 函数。

FLOOR(x)
  • 参数

    • number:可以是整数、浮点数或表达式。
  • 返回值

    • 返回 小于或等于该数值的最大整数
  • 例子:

SELECT FLOOR(3.99), FLOOR(-3.01); -- 3, -4
  • 场景:区间落位、价格阶梯向下取整。
ROUND(number [, decimals]); -- d 为小数位数,缺省为 0
  • 参数

    • number:要处理的数值(整数、浮点数或表达式)。

    • decimals(可选):保留的小数位数。

      • 若省略,默认为 0,即四舍五入到整数。

      • 若为正数,保留对应的小数位数。

      • 若为负数,则对整数部分进行四舍五入。

  • 返回值

    • 按指定规则返回四舍五入后的数值。
  • 例子:

SELECT ROUND(3.14159, 2); -- 3.14
SELECT ROUND(15.5), ROUND(-15.5); -- 16, -16(注意负数规则)
  • 场景:金额展示、评分保留位数。

在数据库中,TRUNCATE 用于 直接截断小数部分,而不是四舍五入。

TRUNCATE(number, decimals);

参数

  • number:要处理的数值。

  • decimals:保留的小数位数(必须指定)。

    • decimals > 0:保留指定位数的小数。

    • decimals = 0:截断到整数。

    • decimals < 0:截断到整数部分的十位、百位、千位……

  • 例子:

SELECT TRUNCATE(3.14159, 2); -- 3.14
  • 场景:严格截断到指定位,避免进位。

在数据库中,MOD 用于求两个数相除后的 余数,也就是常说的“取模”。

MOD(n, m) -- 同义:n % m
  • 例子:
SELECT MOD(10, 3), MOD(-10, 3); -- 1, -1(MySQL 结果与被除数符号一致)
  • 场景:按周期/间隔分组、奇偶判断。

在数据库中,DIV 用于进行 整数除法,即只保留商的整数部分,舍弃小数部分。

dividend DIV divisor
  • 参数

    • dividend:被除数。

    • divisor:除数。

  • 返回值

    • 返回 商的整数部分

    • divisor = 0 时,结果为 NULL

  • 例子:

SELECT 10 DIV 3; -- 3
  • 场景:分桶编号、页码计算。

小贴士:除法时用 x / NULLIF(y,0) 可避免除零错误。

  • GREATEST:返回参数中的 最大值

  • LEAST:返回参数中的 最小值

GREATEST(expr1, expr2, ...);
LEAST(expr1, expr2, ...);
  • 参数

    • 可以是多个数值、字符串、日期等类型。

    • 参数类型需一致或可隐式转换。

  • 返回值

    • GREATEST:返回最大的那个值

    • LEAST:返回最小的那个值

  • 例子:

SELECT GREATEST(3,9,5), LEAST(3,9,5); -- 9, 3

⚠️ 注意:

  • 如果参数中有 NULL,大多数数据库会返回 NULL(MySQL 8.0+ 遵循这个规则)。

  • Oracle、PostgreSQL 等数据库也支持这两个函数。

4.2. INTERVAL 区间定位(返回索引)

Section titled “4.2. INTERVAL 区间定位(返回索引)”

在 MySQL 中,INTERVAL 用于在一组已排序的值中,找出目标值(表达式)所在的区间,并返回 索引编号

INTERVAL(n, a1, a2, a3, ...) -- 返回 n 落在有序断点中的索引
  • 例子:
-- 断点为 60, 80:返回 0/1/2 表示 <60, [60,80), >=80
SELECT INTERVAL(75, 60, 80); -- 1
  • 场景:成绩分档、年龄段分层(与 CASE 组合)。
POW(x,y) / POWER(x,y) -- x^y
SQRT(x) -- 平方根
  • 例子:
SELECT POWER(2,10), SQRT(16); -- 1024, 4
EXP(x) -- e^x
LN(x) / LOG(x) -- 自然对数 ln(x)
LOG10(x) -- 10 为底
LOG2(x) -- 2 为底
  • 例子:
SELECT EXP(1), LN(10), LOG10(1000), LOG2(8);
  • 场景:评分归一化、增长模型、对数刻度。
SIN(x), COS(x), TAN(x)
ASIN(x), ACOS(x), ATAN(x)
ATAN2(y, x) -- 根据 y/x 返回 -π~π 的角度
PI() -- 圆周率
  • 例子:
SELECT PI(), SIN(PI()/2), ATAN2(1,1); -- 3.14159..., 1, 0.78539...
RADIANS(deg), DEGREES(rad)
  • 例子:
SELECT RADIANS(180), DEGREES(PI()); -- 3.14159..., 180
  • 场景:地理/极坐标计算、角度制与弧度制互转。

在数据库中,RAND() 用于生成 0~1 之间的随机浮点数,常用于抽样、随机排序、生成随机主键或测试数据。

RAND([seed]) -- 0~1 之间
  • 参数

    • seed(可选):种子值,用于控制随机序列。

      • 若不指定,系统会根据时间自动生成随机数。

      • 若指定同样的种子值,每次执行结果相同(可复现)。

  • 返回值

    • 返回 0 ≤ 随机数 < 1 的浮点值。
  • 例子:

SELECT RAND(), RAND(42); -- 固定种子可复现
  • 场景:抽样、A/B 测试;注意带 ORDER BY RAND() 在大表会很慢。

7.2. CRC32 校验(返回无符号整数)

Section titled “7.2. CRC32 校验(返回无符号整数)”

在 MySQL 中,CRC32() 是一种 校验函数,用于计算字符串或二进制数据的 CRC-32(循环冗余校验)值
返回结果是一个 32 位无符号整数,常用于校验、数据分片或哈希索引。

CRC32(expr)
  • 参数

    • expr:可以是字符串、数字或二进制值(BLOB、VARBINARY 等)。
  • 返回值

    • 返回一个无符号 32 位整数。

    • 若参数为 NULL,则结果为 NULL

  • 例子:

SELECT CRC32('hello'); -- 32 位校验值
  • 场景:简单一致性校验、分片路由(配合 MOD)。

在 MySQL 中,BIT_COUNT() 用于统计一个整数值的 二进制表示中包含多少个 1

BIT_COUNT(N)
  • 参数

    • N:非负整数(BIGINT 类型范围内)。
  • 返回值

    • 返回整数 N 的二进制形式中 1 的数量。

    • NNULL,则结果为 NULL

  • 例子:

SELECT BIT_COUNT(15); -- 4(1111 中 1 的数量)
  • 场景:位图统计、权限位集合分析。

在 MySQL 中,CONV() 是一个非常实用的 进制转换函数,用于在 不同进制之间(2~36) 进行转换。

CONV(N, from_base, to_base);
  • 参数说明

    参数含义
    N需要转换的数字(可以是字符串形式)
    from_base原始进制(2 ~ 36)
    to_base目标进制(2 ~ 36)
  • 返回值

    • 返回 字符串类型 的目标进制结果。

    • 如果任意参数为 NULL,则返回 NULL

    • 若转换结果为负数,结果字符串前会带 '-'

  • 二进制 / 八进制 / 十进制 / 十六进制 等进制间转换。

  • 用于编码、加密、唯一标识生成、二进制存储优化等场景。

  • 可作为轻量级的 base 转换工具(类似 Integer.toString(x, base))。

SELECT CONV(10, 10, 2); -- 返回 '1010'
表达式含义结果
CONV(10,10,2)10(十进制)转二进制1010
SELECT CONV('1010', 2, 10); -- 返回 '10'
表达式含义结果
CONV('1010',2,10)二进制 1010 → 十进制10
SELECT CONV(255, 10, 16); -- 返回 'FF'
表达式含义结果
CONV(255,10,16)十进制 255 → 十六进制FF
SELECT CONV('FF', 16, 10); -- 返回 '255'
表达式含义结果
CONV('FF',16,10)十六进制 FF → 十进制255

三十六进制(Base36)是常见的短码算法之一(0-9 + A-Z 共 36 位)。

SELECT CONV(2025, 10, 36); -- 返回 '1KP'
表达式含义结果
CONV(2025,10,36)十进制 2025 → Base361KP
SELECT CONV(-15, 10, 2); -- 返回 '-1111'

负号会被保留在结果字符串前。

假设有商品表 products

idcode
110
2255
3512

执行:

SELECT id, code,
CONV(code, 10, 16) AS hex_code
FROM products;

结果:

idcodehex_code
110A
2255FF
3512200
  • 支持的进制范围是 2~36(因为 36 对应 0-9 + A-Z)。

  • 返回结果是字符串(VARCHAR),如果需要数值运算需转换类型。

  • 常配合:

    • LPAD() / RPAD() → 补齐位数;

    • UPPER() → 统一大写;

    • REVERSE() → 编码增强。

FORMAT(x, d [, locale]) -- 返回字符串
  • 例子:
SELECT FORMAT(1234567.891, 2); -- '1,234,567.89'
SELECT FORMAT(1234567.891, 2, 'zh_CN'); -- 本地化
  • 场景:报表/对账单友好展示(注意它返回字符串)。

这些是聚合函数,常与 GROUP BY 配合。

  • SUM(x)AVG(x)MIN(x)MAX(x)COUNT(*)/COUNT(x)

  • 方差/标准差:

    • VAR_POP(x)VAR_SAMP(x)

    • STDDEV_POP(x)STDDEV_SAMP(x)

  • 例子(部门平均年龄与标准差):

SELECT dept_id,
AVG(age) AS avg_age,
STDDEV_SAMP(age) AS std_age
FROM employee
GROUP BY dept_id;
  • 避免除零x / NULLIF(y,0);或 IF(y=0, NULL, x/y)

  • 浮点与小数:金额用 DECIMAL(p,s),避免 FLOAT/DOUBLE 的二进制精度误差

  • ROUND vs TRUNCATE:前者四舍五入,后者直接截断

  • MOD 号的符号:MySQL 中结果符号跟随被除数(第一个参数)

  • 随机排序性能:大表避免 ORDER BY RAND(),可用采样键或预生成随机键替代