如何通过数学运算过滤数值列中包含指定数字的表行?
用数学运算过滤数值列包含指定数字的行
可以通过纯数学运算实现需求,但逻辑复杂度远高于字符串匹配的方式,核心思路是逐位提取数值的每一位数字,再判断是否包含目标数字。以下是具体实现思路和示例:
核心逻辑:逐位提取数字
对于任意数值,我们可以通过「取模(%)」和「整除(FLOOR(x/n))」操作分离每一位数字:
- 取模10可以得到个位数字:
num % 10 - 整除10后再取模10得到十位数字:
FLOOR(num / 10) % 10 - 整除100后取模10得到百位数字:
FLOOR(num / 100) % 10 - 以此类推,覆盖数值可能的所有位数
针对整数列的示例(目标数字为2)
假设你的数值列是无符号整数,可通过多条件OR连接实现:
WHERE -- 检查个位 numeric_column % 10 = 2 -- 检查十位 OR FLOOR(numeric_column / 10) % 10 = 2 -- 检查百位 OR FLOOR(numeric_column / 100) % 10 = 2 -- 检查千位,按需扩展到最大可能位数 OR FLOOR(numeric_column / 1000) % 10 = 2
如果列包含负数,需要先取绝对值避免负号干扰:
WHERE ABS(numeric_column) % 10 = 2 OR FLOOR(ABS(numeric_column) / 10) % 10 = 2 OR FLOOR(ABS(numeric_column) / 100) % 10 = 2
针对带小数的数值列
如果是DECIMAL这类带小数的类型,需要分别处理整数部分和小数部分:
WHERE -- 处理整数部分(以绝对值处理负数) ABS(FLOOR(numeric_column)) % 10 = 2 OR FLOOR(ABS(FLOOR(numeric_column)) / 10) % 10 = 2 -- ... 整数部分其他位 -- 处理小数部分(假设是两位小数,乘以100转为整数) OR FLOOR(ABS(numeric_column - FLOOR(numeric_column)) * 100) % 10 = 2 OR FLOOR(ABS(numeric_column - FLOOR(numeric_column)) * 100 / 10) % 10 = 2
优缺点对比
数学运算方式
- 优点:无需类型转换,严格基于数值操作
- 缺点:
- 必须提前预判列的最大位数,否则要写大量重复的OR条件,维护性极差
- 处理小数场景逻辑非常繁琐
- 无法利用数值索引(和字符串转换方式类似),大表查询性能未必有优势
原字符串匹配方式
- 优点:逻辑简单直观,无需关心数值位数和正负,维护成本极低
- 缺点:数值转字符串后无法利用数值索引,大表查询可能存在性能瓶颈
总结
除非有严格的业务限制禁止类型转换,否则原有的CAST + LIKE方案是更实用的选择。如果一定要用数学运算,核心就是通过取模和整除逐位检查数字。
内容的提问来源于stack exchange,提问作者Jordi
相关产品推荐
相关产品推荐

