从SQL Sever中的字符串模式提取字符串前后

问题描述

我想从给定的文本中提取AC NoAC NameIFS Code。 我可以使用以下代码提取内容,但文本位置可能会发生变化,并且对我不起作用。

例如:

UserInfo="AC No: 644640011906AC Name: AkhilAC Type: CurrentIFSC Code: SBIB0003242"

UserInfo="IFSC Code: SBIB0003242AC No: 644640011906AC Name: AkhilAC Type: Current"

sql

SELECT LTRIM(RTRIM(REPLACE(RIGHT(UserInfo,charindex(':',reverse(UserInfo))-1),'IFSC Code:','')))

请求某人帮助进行SQL查询

解决方法

欢迎来到SQL Server字符串操作的美好世界!

正如其他评论者所说,导入这样的数据是一个糟糕的想法。如果可以,请集中精力获取更好,更结构化的数据源。


也就是说,如果您绝对不能更改数据源并且不想求助于CLR代码,那么您将不得不求助于一些非常丑陋的SQL,这些SQL只会起作用如果您能够保留要捕获的键值名称的顶部,则:

查询

declare @t table(UserID int,UserInfo varchar(200));
insert into @t values
 (1,'IFSC Code: SBIB0003242AC No: 644640011906AC Name: AkhilAC Type: Current'),(2,'AC No: 644640011906AC Name: AkhilAC Type: CurrentIFSC Code: SBIB0003242')
;

with k as
(
    select *
    from(values('AC No:'),('AC Name:'),('AC Type:'),('IFSC Code:')) as k(k)
)
select UserID,k.k,ltrim(replace(substring(v.v,c.s,c.e-c.s),'')) as v
from @t as t
    cross join k
    cross apply(values(replace(
                         replace(
                           replace(
                             replace(
                               t.UserInfo,'AC No:',case when k.k = 'AC No:' then 'AC No:' else '|' end
                               ),'AC Name:',case when k.k = 'AC Name:' then 'AC Name:' else '|' end
                             ),'AC Type:',case when k.k = 'AC Type:' then 'AC Type:' else '|' end
                           ),'IFSC Code:',case when k.k = 'IFSC Code:' then 'IFSC Code:' else '|' end
                         ) + '|'
                      )
               ) as v(v)
    cross apply(values(patindex('%' + k.k + '%',v.v),charindex('|',v.v,patindex('%' + k.k + '%',v.v))
                      )
               ) as c(s,e);

输出

+--------+------------+--------------+
| UserID |     k      |      v       |
+--------+------------+--------------+
|      1 | AC No:     | 644640011906 |
|      1 | AC Name:   | Akhil        |
|      1 | AC Type:   | Current      |
|      1 | IFSC Code: | SBIB0003242  |
|      2 | AC No:     | 644640011906 |
|      2 | AC Name:   | Akhil        |
|      2 | AC Type:   | Current      |
|      2 | IFSC Code: | SBIB0003242  |
+--------+------------+--------------+
,
select  
SUBSTRING(UserInfo,CHARINDEX('AC No: ',UserInfo)+7,( select min(x*(case x when 0 then null else 1 end)) 
       from 
       ( 
         VALUES 
         (CHARINDEX('AC Name: ',UserInfo,UserInfo)+7)),(CHARINDEX('AC Type: ',(CHARINDEX('IFSC Code: ',(LEN(UserInfo)+1)
       )
       AS value(x)
       
 ) - (CHARINDEX('AC No: ',UserInfo)+7)

)
as AC_No,SUBSTRING(UserInfo,CHARINDEX('AC Name: ',UserInfo)+9,( select min(x*(case x when 0 then null else 1 end)) 
       from 
       ( 
         VALUES 
         (CHARINDEX('AC No: ',UserInfo)+9)),(LEN(UserInfo)+1)
       )
       AS value(x)
       
 ) - (CHARINDEX('AC Name: ',UserInfo)+9)
)
as AC_Name,CHARINDEX('IFSC Code: ',UserInfo)+11,UserInfo)+11)),(CHARINDEX('AC Name: ',(LEN(UserInfo)+1)
       )
       AS value(x)
       
 ) - (CHARINDEX('IFSC Code: ',UserInfo)+11)

)
as IFSC_Code

from test

然后,最好在将数据加载到暂存表等中并将其存储在生产表的适当字段中时执行一次。

小提琴示例: https://dbfiddle.uk/?rdbms=sqlserver_2014&fiddle=a5fdfbbd6a0b4657602af39744993a91