如何在SQL Server中移除字符串字段中的字母字符?
现有SQL Server数据库中的
[dbo].[orders]表结构及数据如下:CREATE TABLE [dbo].[orders]( [orderid] [varchar](50) NULL, [ordernumber] [varchar](100) NULL ) INSERT [dbo].[orders] ([orderid], [ordernumber]) VALUES (N'1', N'ab123c2') INSERT [dbo].[orders] ([orderid], [ordernumber]) VALUES (N'2', N'4xHx32a') INSERT [dbo].[orders] ([orderid], [ordernumber]) VALUES (N'3', N'h2b58B21b22')期望得到只保留
ordernumber中数字的结果:
orderid Ordernumber 1 1232 2 432 3 2582122 之前尝试用多次
REPLACE逐个去除字母,操作繁琐,想找更简便的方法。
简便的解决方案
方法1:SQL Server 2017+ 用 TRANSLATE + REPLACE(最简洁)
如果你的SQL Server版本是2017或更高,这是最省事的方案——利用TRANSLATE一次性把所有大小写字母映射到同一个占位符,再用一次REPLACE清空所有占位符:
SELECT orderid, REPLACE( TRANSLATE(ordernumber, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ', REPLICATE('@', 52) ), '@', '' ) AS Ordernumber FROM orders;
原理:TRANSLATE会把第一个参数里的每个字母,对应替换成第二个参数里的@(52个占位符刚好覆盖26个大小写字母),最后批量移除所有@就得到纯数字结果。
方法2:创建自定义标量函数(兼容所有SQL Server版本)
如果你的版本低于2017,可以创建一个通用的工具函数,后续查询直接调用即可,不用每次写一堆替换逻辑:
CREATE FUNCTION dbo.RemoveNonDigits(@input VARCHAR(MAX)) RETURNS VARCHAR(MAX) AS BEGIN WHILE PATINDEX('%[^0-9]%', @input) > 0 BEGIN -- 找到第一个非数字字符,用STUFF删除它 SET @input = STUFF(@input, PATINDEX('%[^0-9]%', @input), 1, '') END RETURN @input END GO -- 调用函数查询 SELECT orderid, dbo.RemoveNonDigits(ordernumber) AS Ordernumber FROM orders;
方法3:递归CTE(无需创建函数,兼容低版本)
不想创建函数的话,用递归CTE也能实现相同效果,全程在查询里处理:
WITH RecursiveCTE AS ( SELECT orderid, ordernumber, 1 AS pos FROM orders UNION ALL SELECT orderid, -- 遇到非数字字符就删除 STUFF(ordernumber, pos, 1, ''), -- 数字字符位置不变,非数字删除后位置保持当前值继续检查 CASE WHEN SUBSTRING(ordernumber, pos, 1) LIKE '[0-9]' THEN pos + 1 ELSE pos END FROM RecursiveCTE WHERE pos <= LEN(ordernumber) ) SELECT orderid, MAX(ordernumber) AS Ordernumber FROM RecursiveCTE GROUP BY orderid ORDER BY orderid;
内容的提问来源于stack exchange,提问作者jaiparkumar




