用于检索特定字符串的SQL语句

问题描述 投票:-2回答:4

我正在尝试从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
sql sql-server tsql sql-server-2012
4个回答
1
投票

这应该做到这一点。

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]) 

1
投票

你可以试试这个:

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

您可以看到,我使用CASTREPLACE的技巧将您的字符串转换为XML,允许分别处理每个部分。 XPath到第一个元素x[1]返回Account或Random,而第二个x[2]返回数字。

我使用的第二个技巧是XQuerys隐含的try_cast值的能力。如果该值无法转换为xs:int?,则将以NULL的形式返回。


1
投票

这确保了“帐号#”后的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


1
投票

我会使用http://sqlfiddle.com/#!6/cd617/2substring()函数来获取数值

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
© www.soinside.com 2019 - 2024. All rights reserved.