首页/数据/SQL 速查/SELECT 计算列与表达式

SELECT 计算列与表达式

在 SELECT 里直接做算术得到派生列:支持括号、四则运算与取模;注意整数除法与除零行为在 MySQL、PostgreSQL 间不同。

SQL 速查数据更新于 2026-10-13

计算列是什么

计算列是在 SELECT 里直接用表达式算出来的派生列,支持括号、四则运算与取模。它只存在于本次结果集,不会写回表,也没有对应索引。运算符优先级与数学一致:乘除取模高于加减,同级从左到右,括号可以改变顺序。整数除法与除零的行为在 MySQL 与 PostgreSQL 之间不同,涉及金额、比率、均值的计算要特别留意类型,必要时先做显式类型转换。

基本信息

运算符+ - * / %(整除可用 DIV,取模也可写 MOD(a,b))
优先级* / % 高于 + -,同级从左到右
NULL 参与任一操作数为 NULL,结果即为 NULL
除零MySQL 返回 NULL 并告警;PostgreSQL 直接报 division by zero
整数除法MySQL 得小数;PostgreSQL 两整数相除截断
适用平台标准 SQL 写法,MySQL 8.0 与 PostgreSQL 均支持

典型使用场景

  • 算金额与小计:price * qty AS amount,避免前端重复实现口径
  • 算含税价与折扣:先乘再加再 ROUND,注意舍入位置
  • 算占比与差额:part * 100.0 / total,乘 100.0 规避整数除法
  • 算分页偏移:偏移量等于页码减一乘以每页条数
  • 算账龄与逾期天数:配合日期函数得到天数区间
  • 归一化展示:把存储值换算成业务单位后再输出

示例

示例
SELECT item_id,
       price,                                  # 单价
       qty,                                    # 数量
       price * qty                 AS amount,  # 小计
       ROUND(price * qty * 0.06, 2) AS tax,     # 税额保留两位
       (price * qty - discount)    AS payable   # 括号改变优先级
FROM order_items;

整数除法与除零

整数除法与除零
-- MySQL:整数相除得到小数
SELECT 5 / 2;              # 2.5000
SELECT 7 DIV 2;            # 3,整除用 DIV

-- PostgreSQL:整数相除会截断
SELECT 5 / 2;              # 2
SELECT 5::numeric / 2;     # 2.5000000000000000

-- 除零:先兜底再计算
SELECT 1 / NULLIF(denominator, 0);   # 分母为 0 时整体返回 NULL

表达式与结果类型

表达式结果注意事项
price * qty乘积两整数列相乘仍是整数,超范围会溢出
amount * 1.06小数常量是浮点字面量,金额应改用定点类型
ROUND(x, 2)四舍五入到两位只改变精度,不改变底层类型
ABS(a - b)差值绝对值对账比差常用
MOD(a, b)余数b 为 0 时 MySQL 返回 NULL
除数为 0 时 MySQL 返回 NULL 并给出告警,PostgreSQL 直接中断语句;业务计算前用 NULLIF 兜底分母最稳妥。
PostgreSQL 中两个整数列相除会截断小数,比率与均值计算要先 CAST 成 numeric,或乘一个带小数点的常量。
FLOAT 与 DOUBLE 是近似值,0.1 加 0.2 不等于 0.3;涉及金额、税率、库存数量的运算统一用 DECIMAL 或 numeric。

使用要点

  • 给计算列起别名,后续 ORDER BY 与上层引用都更清楚
  • 表达式里的列无法用普通索引过滤,WHERE 中把计算移到常量一侧
  • 同一条 SQL 里重复用到的表达式提取成别名或 CTE
  • 金额相关运算全程用定点类型,最后一步再按要求舍入
  • 结果涉及除法时先想清楚分母为 0 与 NULL 的处理方式
  • 业务口径写进注释或文档,避免同一指标在不同查询里算法不同

易错点

  • PostgreSQL 里两个整数列相除会截断,金额与比率计算要先把值 CAST 成 numeric
  • 浮点数求和与比较存在精度误差,涉及金额用 DECIMAL 或 numeric 类型
  • 表达式包住列会让索引失效,WHERE 里对列做运算要改成对常量做运算
  • 同一 SQL 里重复写长表达式而不提取别名,改口径时容易漏改其中一处
  • 除数为 0 时未做兜底,PostgreSQL 直接报错中断整个查询

数据来源与参考

  • MySQL 8.0 Reference Manual · Arithmetic Operators
  • PostgreSQL Documentation · Mathematical Operators
​‌‌​​‌​​​‌‌​‌‌‌‌​‌‌​​​‌‌​‌‌‌​​‌‌​​‌​‌‌‌​​‌‌‌​​​‌​‌‌​‌​​‌​‌‌‌​​​‌​‌‌​‌​​‌​‌‌​​​‌‌​‌‌‌​‌​​​‌‌​‌‌‌‌​​‌​‌‌‌​​‌‌​​​‌‌​‌‌​‌‌‌‌​‌‌​‌‌​‌