从righ no substring开始从字符串中提取Text。 SQL

时间:2016-12-13 16:01:11

标签: sql sql-server sql-server-2012

我有一个包含变量名称的列,例如

UB121216SVC0054
12122016TH10076
UB121216OH10058

我想从右边开始提取字母。

SVC
TH
OH

由于字母和数字的数量不同,我不能使用子字符串来指定第一个和最后一个字符。

我该如何解决这个问题?

3 个答案:

答案 0 :(得分:1)

这适用于所有测试用例...... 它最初修剪所有尾随数字,然后只对前面的字符进行子字符串,直到找到一个数字。将@var更改为任何测试用例。

declare @var varchar(50) = ' '

select case when @var is not null and @var <> '' then 
      right(reverse(substring(reverse(@var),PATINDEX('%[^0-9]%',reverse(@var)),len(@var) - PATINDEX('%[^0-9]%',reverse(@var)))),PATINDEX('%[0-9]%',reverse(reverse(substring(reverse(@var),PATINDEX('%[^0-9]%',reverse(@var)),len(@var) - PATINDEX('%[^0-9]%',reverse(@var)))))) - 1)
      else null end

修改

declare @var varchar(50) = 'claim_ud   H4748sd115600'

select case 
      when @var is not null and @var <> '' then
            case 
                when  PATINDEX('% %',@var) = 0 then
                right(reverse(substring(reverse(@var),PATINDEX('%[^0-9]%',reverse(@var)),len(@var) - PATINDEX('%[^0-9]%',reverse(@var)))),PATINDEX('%[0-9]%',reverse(reverse(substring(reverse(@var),PATINDEX('%[^0-9]%',reverse(@var)),len(@var) - PATINDEX('%[^0-9]%',reverse(@var)))))) - 1)
                else
                right(reverse(substring(reverse(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1)),PATINDEX('%[^0-9]%',reverse(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1))),len(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1)) - PATINDEX('%[^0-9]%',reverse(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1))))),PATINDEX('%[0-9]%',reverse(reverse(substring(reverse(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1)),PATINDEX('%[^0-9]%',reverse(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1))),len(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1)) - PATINDEX('%[^0-9]%',reverse(stuff(@var,PATINDEX('% %',@var),PATINDEX('% %',reverse(@var)) - PATINDEX('% %',@var),1))))))) - 1)
                end
      else null end

答案 1 :(得分:0)

对于您提供的示例,以下代码似乎是一个简单的解决方案:

select (case when substring(col, 11, 1) between '0' and '9'
             then substring(col, 9, 2)
             else substring(col, 9, 3)
        end)

这假设代码是2或3个字符,并始终从第9个位置开始。

答案 2 :(得分:0)

请注意,此版本与Radu的代码(上图)创建了相同的基本执行计划,但我发现它更具可读性。包括评论。

-- Create a testing table
CREATE TABLE #codes (code varchar(32))
GO
INSERT INTO #codes Values ('UB121216SVC0054')
INSERT INTO #codes Values ('12122016TH10076')
INSERT INTO #codes Values ('UB121216OH10058')
GO
-- Get the substring data
SELECT   -- Get the data up to the first non-letter
    Reverse(LEFT(fragment, patindex('%[^A-Za-z]%', fragment)-1)) as substr
FROM (  -- trim the field at the first letter
    SELECT SUBSTRING(rcode, patindex('%[A-Za-z]%', rcode), len(rcode)) as fragment
    FROM (  -- Working with the reversed values
        SELECT reverse(code) as rcode 
        FROM #codes
        ) as ReverseTable
    ) as WorkTable