我正在尝试从Notes列中提取数字。如果数字前面有特定的字符串,我只想要数字。该数字可以是5或6个字符长,并且最终可能最多达到7个或更多。
我需要利用LEFT,RIGHT,CHARINDEX或SUBSTRING的哪种组合来实现这一目标?或者我是否需要完全使用其他东西?我无法弄清楚那些有用的东西。
Notes列包含许多不同类型的注释,因此一直困难重重。
提前致谢。
编辑:对不起,这里有一些示例数据和预期输出。
EDIT2:再次抱歉,我应该让样本数据更加清晰。有多个号码,但我只想要前面带有'帐号#'的号码。
Sample Data Output
'Account #12345' 12345
'Account #123456' 123456
'Random #12345' NULL
'Account #1234567' 1234567
'12345' NULL
'Random' NULL
这应该做到这一点。
SELECT YT.[Sample Data],
S2.[Output]
FROM YourTable YT
CROSS APPLY (SELECT 'Account #') S(S)
CROSS APPLY (SELECT CASE
WHEN CHARINDEX(S.S, [Sample Data]) > 0
THEN SUBSTRING([Sample Data], LEN(S.S) + CHARINDEX(S.S, [Sample Data]), 8000)
END) S1(StringWithNumberAtStart)
CROSS APPLY (SELECT LEFT(StringWithNumberAtStart,
PATINDEX('%[^0-9]%', StringWithNumberAtStart + 'X'))) S2([Output])
你可以试试这个:
DECLARE @dummyTbl TABLE(YourString VARCHAR(100));
INSERT INTO @dummyTbl VALUES
('Account #12345')
,('Account #123456')
,('Random # note')
,('Account #1234567');
WITH Casted AS
(
SELECT YourString
,CAST('<x>' + REPLACE(YourString,' #','</x><x>') + '</x>' AS XML) toXML
FROM @dummyTbl
)
SELECT YourString
,toXML
,toXML.value('x[1]','nvarchar(max)') AS KeyText
,toXML.value('x[2] cast as xs:int?','int') AS NumberIfCastable
FROM Casted;
结果
YourString toXML KeyText NumberIfCastable
Account #12345 <x>Account</x><x>12345</x> Account 12345
Account #123456 <x>Account</x><x>123456</x> Account 123456
Random # note <x>Random</x><x> note</x> Random NULL
Account #1234567 <x>Account</x><x>1234567</x> Account 1234567
您可以看到,我使用CAST
和REPLACE
的技巧将您的字符串转换为XML,允许分别处理每个部分。 XPath
到第一个元素x[1]
返回Account或Random,而第二个x[2]
返回数字。
我使用的第二个技巧是XQuery
s隐含的try_cast值的能力。如果该值无法转换为xs:int?
,则将以NULL
的形式返回。
这确保了“帐号#”后的5位数字,并且在更长时间后要求输入isnumeric。这不是您的要求的100%,而是一种方法。 Isnumeric函数以特殊方式工作https://docs.microsoft.com/en-us/sql/t-sql/functions/isnumeric-transact-sql
--len('Account #') is 9
select case when Notes like 'Account #[0-9][0-9][0-9][0-9][0-9]%'
and isnumeric(right(Notes,len(Notes)-9) )=1 then right(Notes,len(Notes)-9)
else null end
from myTable
对于SQL Server 2012+,请使用try_parse qazxsw poi
https://docs.microsoft.com/en-us/sql/t-sql/functions/try-parse-transact-sql
SQLFIDDLE select case when Notes like 'Account #[0-9][0-9][0-9][0-9][0-9]%'
and isnumeric(try_parse(right(Notes,len(Notes)-9) as bigint ))=1
then right(Notes,len(Notes)-9) else null end
from myTable
我会使用http://sqlfiddle.com/#!6/cd617/2和substring()
函数来获取数值
patindex()
编辑:
在你提出问题之后改变问题很粗鲁。它可以使答案无效,而答案又可以吸引投票。
好吧,我根据编辑的帖子更新了答案。
SELECT sampledata, SUBSTRING(sampledata, PATINDEX('%[1-9]%', SampleData),
case
when(LEN(sampledata)-PATINDEX('%[1-9]%', SampleData)+1) > LEN(SampleData)
then 0
else LEN(sampledata)-PATINDEX('%[1-9]%', SampleData)+1
end) numericvalues
FROM table;
结果:
select sampledata,
case
when patindex('%Account #%', sampledata) > 0
then SUBSTRING(sampledata, PATINDEX('%[1-9]%', sampledata), LEN(sampledata)-PATINDEX('%[1-9]%', sampledata)+1)
end [Output]
from table