SQL Server仅在=或仅数字之后提取数据

时间:2018-10-15 21:26:32

标签: sql sql-server regex tsql

正则表达式似乎是理想的选择,但有些团队成员不喜欢正则表达式...

问题:(从大型机平面文件导入)列中的数据看起来像2种不同的方式

BreakID = 83823737237
OR
MFR BreakID=482883 

因此,差异是数字前的空格,等于等号之前的两个字母字符的长度都变化,最后数字的长度也将变化。

似乎我有几种方法,
1. =符号和剪裁后的所有内容? 2.正则表达式,仅获取数字?

因此,我找到了这段代码,其中我假定PATINDEX是-tsql中进行正则表达式的标准方式?这是什么“字符串”?

SELECT SUBSTRING(string, PATINDEX('%[0-9]%', string), PATINDEX('%[0-9][^0-9]%', string + 't') - PATINDEX('%[0-9]%', 
                string) + 1) AS Number

如何通过最佳做法解决?

4 个答案:

答案 0 :(得分:1)

似乎是substringreplacecharindex的好用例

我们从=之后的第一个值开始的所有子字符串中获取子字符串,直到99位数字(或您要输入的位数)。如果有空格,我们使用replace来消除开头的空格。

select replace(substring(stringColumn,charindex('=',stringColumn) + 1,99),' ','')

答案 1 :(得分:1)

答案与scsimon略有不同。当我必须在字符串末尾获取val时,通常会走这条路线。反转字符串并获取键值的第一个实例的位置(在这种情况下为'=')。使用charindex获得该位置,然后使用该charindex值获取RIGHT()字符。

DECLARE @val1 VARCHAR(100) = 'BreakID = 83823737237'
DECLARE @val2 VARCHAR(100) = 'MFR BreakID=482883'

SELECT 
LTRIM(RTRIM(RIGHT(@val1, CHARINDEX('=', REVERSE(@val1), 0)-1)))
,LTRIM(RTRIM(RIGHT(@val2, CHARINDEX('=', REVERSE(@val2), 0)-1)))

如果您遇到奇怪的情况,例如您的数据中有一家名为SQL=Cool的公司,并且需要一个ID:

,此解决方案将非常有用。
'SQL=CoolID = 12345'

您仍然希望获得12345。

答案 2 :(得分:0)

该解决方案很好且用途广泛,尽管听起来您的字符串将始终带有=,所以您可以根据需要编写更具体的内容。

该解决方案可以找到第一个数字字符串的起始位置:

PATINDEX('%[0-9]%', string)

并找到该数字字符串之后的第一个非数字字符的位置(如果在字符串末尾添加't',以防它以数字结尾,否则会引发错误):

PATINDEX('%[0-9][^0-9]%', string + 't')

最后,它从结束位置减去数字的起始位置,以找到数字字符串的长度,并用子字符串拉出该长度:

SELECT SUBSTRING(string, PATINDEX('%[0-9]%', string), PATINDEX('%[0-9][^0-9]%', string + 't') - PATINDEX('%[0-9]%', 
                string) + 1) AS Number

此处“字符串”是一个占位符,应替换为您的列名。另外,在tsql中测试像这样的东西的最简单方法是使用变量:

DECLARE @string varchar(100) = 'foo bar la la la 83823737237'

SELECT SUBSTRING(@string, PATINDEX('%[0-9]%', @string), PATINDEX('%[0-9][^0-9]%', @string + 't') - PATINDEX('%[0-9]%', 
                @string) + 1) AS Number

输出:

83823737237

答案 3 :(得分:0)

Kaizen:寻求简单的解决方案,而不是完美的解决方案

SELECT substring(c, charindex('=', c), 999)

我假设您要插入的列是某种数字。 Sqlserver在转换为数字时不关心前导空格

如果要放在字符串列中,则将其包装在ltrim()

现在您的问题

  

1 ..修剪

当然,如上所述

  

2个正则表达式...

除非使用CLR,否则不会在sqlserver中实现

  

PATINDEX ...

就像正则表达式,但是它是一个非常有限的子集,仅执行搜索,仅返回一个字符串索引,不捕获,具有有限/无字符类。比正则表达式更像dos / vb6通配符/ like

  

...最佳做法?

简单地看一下;您将在=后面得到字符串的一部分,而不是降落在月球上。像这样的次要优化的最佳解决方案是,它需要下一个接替您工作的人的脑力劳动中最少的精力,以赶上它(它将在20年内继续使用):)