取绝对值与判断正负
两个基础数学函数:取绝对值的函数把负数变成正数,符号函数返回负一、零、正一。它们的典型用途不是做数学题,而是表达业务意图——算误差时只看偏离幅度不看方向,生成涨跌标记时只看方向不看幅度,比较浮点数时用一个容差代替等号。浮点运算不能直接比较相等是这组函数最常见的出场理由。
基本信息
| 适用平台 | MySQL 8.0 / PostgreSQL 12 及以上,两库都提供 |
|---|---|
| 取值函数 | 返回数值的绝对值,输入负数得到正数 |
| 符号函数 | 返回负一、零或正一,输入空值返回空值 |
| 返回类型 | PostgreSQL 保持原数值类型,整数返回整数 |
| 类型严格度 | PostgreSQL 不做隐式转换,传字符串会报类型错误 |
典型使用场景
- 浮点误差比较:判断两个计算结果的差是否小于容差
- 涨跌标记:按符号函数结果生成上升、持平、下降三种状态
- 金额方向:把收支方向从金额本身剥离出来单独判断
- 偏离幅度排序:按与基准值的距离排序,找出偏差最大的记录
- 埋点校验:比对两套统计口径的结果差异,超过阈值时告警
常见写法
常见写法
-- 基础用法
SELECT ABS(-3.5); -- 结果是 3.5
SELECT SIGN(-12), SIGN(0), SIGN(7); -- 结果是 -1, 0, 1
-- 浮点误差容忍比较:不要用等号比较浮点数
SELECT * FROM metrics
WHERE ABS(target - actual) < 0.001;
-- 生成涨跌标记,供报表直接展示
SELECT dt, close_price,
CASE SIGN(close_price - LAG(close_price) OVER (ORDER BY dt))
WHEN 1 THEN 'up' WHEN -1 THEN 'down' ELSE 'flat' END AS trend
FROM quotes;
-- 按偏离幅度排序,找出偏差最大的记录
SELECT id, target, actual, ABS(target - actual) AS gap
FROM metrics ORDER BY gap DESC LIMIT 20;输入类型的行为差异
| 输入情况 | MySQL 行为 | PostgreSQL 行为 |
|---|---|---|
| 整数 | 返回整数 | 返回整数 |
| 小数 | 返回小数 | 保持小数精度与类型 |
| 字符串数字 | 隐式转成数值后计算 | 报类型错误,需要显式转换 |
| 空值 | 返回空值 | 返回空值 |
| 极值与溢出 | 受数值类型范围约束 | 同样受类型范围约束 |
用容差比较替代等号是数值列的常规做法,特别是金额经过多次换算、坐标经过投影计算之后。容差取值要结合业务精度:金额场景通常取最小货币单位的一半以内,比率场景按需要的精度定。
PostgreSQL 的参数类型要求严格,把文本列直接传给这两个函数会报错。数据来源是文本时,先做显式类型转换,转换失败会抛错,可以通过正则预校验减少脏数据带来的中断。