我有一个varchar(200)列,其中包含以下条目,
ABC123124_A12312
ABC123_A1212
ABC123124_B12312
AC123124_AD12312
A12312_123
ETC..
我想用单个数字替换一系列数字,*
以便可以对表中不同的非数字模式进行分组。
这组的结果是
ABC*_A*
ABC*_B*
AC*_AD*
A*_*
我在下面编写了以下原始查询,它可以正常工作,但是在一个巨大的表上运行需要很长时间。
我需要帮助来重写或编辑它以提高它的性能。SQL Server 2014
-- 1. replace all numeric characters with '*'
-- 2. replace multiple consecutive '*' with just a single '*'
SELECT REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE
(REPLACE(SampleID, '0', '*'),
'1', '*'),
'2', '*'),
'3', '*'),
'4', '*'),
'5', '*'),
'6', '*'),
'7', '*'),
'8', '*'),
'9', '*')
, '*', '~*') -- replace each occurrence of '*' with '~*' (token plus asterisk)
, '*~', '') -- replace in the result of the previous step each occurrence of '*~' (asterisk plus token) with '' (an empty string)
, '~*', '*') -- replace in the result of the previous step each occurrence of '~*' (token plus asterisk) with '*' (asterisk)
AS Pattern
FROM TABLE_X
数据
该列包括字母和数字[A-Za-z0-9]
,还可能包括特殊字符/
和_
. 我想用 替换任何数字序列*
,但我不知道该条目是否有特殊字符,如果有,有多少特殊字符。
我也不知道条目中有多少个数字序列。我所知道的是,一个条目必须至少有 1 个数字序列。
有两个因素对性能很重要:
减少字符串操作的数量。
您可能会发现可以使用 eg 来实现您需要的内容
CHARINDEX
并找到组的开始和结束,而不是每次都对整个字符串PATINDEX
执行很多操作。REPLACE
使用提供正确结果的最便宜的排序规则。
二进制排序规则是最便宜的。SQL 排序规则(仅在非 Unicode 数据上)要贵一些。Windows 排序规则要贵得多。
例如:
db<>小提琴演示
该示例依赖于一个永久的数字表。如果需要,足够的表格
varchar(200)
是:如果这不是更快,您可能会发现单独使用二进制排序规则会充分加快现有实现的速度。要实现这一点,请将您的代码的一行更改为:
SQL Server 2017 或更高版本的用户可以利用内置
TRANSLATE
函数,它的性能可能比嵌套REPLACE
调用更好。您还可以使用通用的正则表达式 CLR 函数,或者在 SQLCLR 中为这个特定任务实现一些自定义的东西。参见例如SQL Server:用通配符替换?
使用SQL# 库,一个完整的解决方案是:
完整的正则表达式支持对于这个任务来说是多余的,所以如果你能够使用 SQLCLR,为你的需要编写一个特定的函数可能是所有性能最好的解决方案。
以您喜欢的任何方式创建数字表,
或者您
2000 ,3000
只能在 tblNumber 中编号,因为没有字符串会那么长。缩短一张数字表。使用 ITVF,
用法 :