在SQL的实际使用场景中,我们经常会遇到需要从文本字段中筛选出包含数字的行的情况,比如从用户留言、商品描述、订单备注这类非结构化文本中提取包含数字的内容。这类需求如果通过普通的LIKE模糊查询实现会非常繁琐,而使用正则表达式匹配可以快速精准地完成筛选。

不同数据库的正则表达式支持情况
主流的关系型数据库大多都支持正则表达式查询,但对应的语法函数存在差异,下面先梳理常见数据库的正则匹配函数:
| 数据库类型 | 正则匹配函数 | 是否支持正则提取 |
|---|---|---|
| MySQL | REGEXP / RLIKE | 是(需配合REGEXP_SUBSTR) |
| PostgreSQL | ~ 操作符 / regexp_match函数 | 是 |
| Oracle | REGEXP_LIKE函数 | 是 |
| SQL Server | 无原生正则函数,需借助CLR集成 | 否 |
匹配数字的正则表达式基础写法
要匹配包含数字的行,核心的正则表达式规则是[0-9]或者d,两者的作用都是匹配单个0到9之间的数字。如果需要匹配连续的数字,可以在后面添加量词,比如[0-9]+表示匹配至少一个连续数字,d{3}表示匹配恰好3个连续数字。
需要注意在SQL的字符串中,反斜杠通常是转义字符,所以如果使用d的写法,可能需要写成\d,具体要看数据库的字符串转义规则。
各数据库的具体查询示例
MySQL查询包含数字的行
MySQL使用REGEXP或者RLIKE操作符来判断字段是否匹配正则表达式,以下是查询user_remark表中备注字段包含数字的行的示例:
-- 查询user_remark表中remark字段包含任意数字的记录
SELECT *
FROM user_remark
WHERE remark REGEXP '[0-9]+';
-- 如果需要匹配恰好3个连续数字的行,写法如下
SELECT *
FROM user_remark
WHERE remark REGEXP '[0-9]{3}';
PostgreSQL查询包含数字的行
PostgreSQL使用~操作符进行正则匹配,同样支持[0-9]和d两种写法,示例如下:
-- 查询product表中description字段包含数字的记录 SELECT * FROM product WHERE description ~ '[0-9]+'; -- 使用d写法,注意PostgreSQL中字符串默认不转义,所以可以直接写d SELECT * FROM product WHERE description ~ 'd+';
Oracle查询包含数字的行
Oracle使用REGEXP_LIKE函数进行正则匹配,第一个参数是字段名,第二个参数是正则表达式,示例如下:
-- 查询order_note表中note字段包含数字的记录
SELECT *
FROM order_note
WHERE REGEXP_LIKE(note, '[0-9]+');
-- 匹配包含连续2到4位数字的行
SELECT *
FROM order_note
WHERE REGEXP_LIKE(note, '[0-9]{2,4}');
注意事项
- 如果字段值可能包含NULL,正则匹配会自动排除NULL值,不需要额外添加
IS NOT NULL条件,除非你需要同时处理NULL的情况。 - 不同数据库对正则语法的支持细节有差异,比如部分数据库不支持
d简写,优先使用[0-9]的写法兼容性更好。 - 如果只需要匹配数字开头或者数字结尾的行,可以调整正则表达式,比如
^[0-9]匹配数字开头,[0-9]$匹配数字结尾。
扩展:提取字段中的数字内容
如果需要不仅筛选包含数字的行,还要提取出字段中的数字内容,可以使用各数据库提供的正则提取函数,比如MySQL的REGEXP_SUBSTR:
-- 从remark字段中提取第一个连续的数字串 SELECT remark, REGEXP_SUBSTR(remark, '[0-9]+') AS extract_num FROM user_remark WHERE remark REGEXP '[0-9]+';