T-SQL中兼容提取横杠前3/4位数字的方法及CHARINDEX用法排查
SQL Server提取横杠前数字的兼容方案
正确使用CHARINDEX的写法
你之前用CHARINDEX返回NULL,大概率是没处理无分隔符的异常记录,或者搞反了CHARINDEX的参数顺序(它第一个参数是要查找的字符,第二个是目标字符串)。正确提取第一个-前所有数字的语句如下:
SELECT LEFT(idnumber, CHARINDEX('-', idnumber) - 1) AS prefix_number FROM [dbo].[mytable]
原理:CHARINDEX('-', idnumber)返回第一个-的位置,减1就是前缀数字的长度,用LEFT截取对应长度即可,不管是3位还是4位都能适配。
处理异常场景
如果表中存在不含-的idnumber记录,上面的语句会返回NULL(因为CHARINDEX返回0,减1后是-1,LEFT对负数长度返回NULL)。可以用CASE语句处理这种情况:
SELECT CASE WHEN CHARINDEX('-', idnumber) > 0 THEN LEFT(idnumber, CHARINDEX('-', idnumber) - 1) ELSE idnumber -- 这里可以替换成你需要的默认值,比如''或者'0' END AS prefix_number FROM [dbo].[mytable]
或者用NULLIF简化逻辑(如果允许无分隔符时返回NULL):
SELECT LEFT(idnumber, NULLIF(CHARINDEX('-', idnumber), 0) - 1) AS prefix_number FROM [dbo].[mytable]
其他替代方案
1. SUBSTRING组合写法
和LEFT逻辑完全一致,只是换用SUBSTRING函数:
SELECT SUBSTRING(idnumber, 1, CHARINDEX('-', idnumber) - 1) AS prefix_number FROM [dbo].[mytable]
2. 字符串拆分法(SQL Server 2019+)
如果习惯用拆分的思路,可以用STRING_SPLIT配合行号取第一个元素(SQL Server 2022才支持ordinal参数,2019需要用ROW_NUMBER生成序号):
SELECT t.idnumber, split.value AS prefix_number FROM [dbo].[mytable] t CROSS APPLY ( SELECT value, ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS seq FROM STRING_SPLIT(t.idnumber, '-') ) split WHERE split.seq = 1
这种写法可读性更强,但性能略低于直接用CHARINDEX,适合复杂拆分场景。
内容的提问来源于stack exchange,提问作者luisdev
相关产品推荐
相关产品推荐

