Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 提取字符串中字符第二次出现的权限_Sql Server_String_Tsql_Substring_Charindex - Fatal编程技术网

Sql server 提取字符串中字符第二次出现的权限

Sql server 提取字符串中字符第二次出现的权限,sql-server,string,tsql,substring,charindex,Sql Server,String,Tsql,Substring,Charindex,我正在使用SQL Server 2014 我有一个表,其中有一个名为“addr”的字段,其中包含如下字符串值: ROOM 1 101 My Street; My Town ROOM 2 101 My Street; My Town ROOM A 123 My Crescent; My Old Town ROOM A 12a My Avenue; My Very Old Town SELECT CAST('<x>' + REPLACE(addr, ' ', '</x>&l

我正在使用SQL Server 2014

我有一个表,其中有一个名为“addr”的字段,其中包含如下字符串值:

ROOM 1 101 My Street; My Town
ROOM 2 101 My Street; My Town
ROOM A 123 My Crescent; My Old Town
ROOM A 12a My Avenue; My Very Old Town
SELECT CAST('<x>' + REPLACE(addr, ' ', '</x><x>') + '</x>' AS XML).value('/x[3]', 'varchar(200)') from MyTable;
我需要做两件事:

  • 提取第二个“”和第三个“”之间的数字 导致:
  • 提取第三个“”之后的文本,直到第一个“;”导致:
  • 我该怎么做

    我试过:

    SELECT CAST('<x>' + REPLACE(addr, ' ', '</x><x>') + '</x>' AS XML).value('/x[1]', 'varchar(200)') from mytable;
    
    从mytable中选择CAST(''+REPLACE(addr','')+''作为XML);
    
    但这会导致“房间”

    更新:

    为了提取第二个和第三个之间的数字,我使用了以下方法:

    ROOM 1 101 My Street; My Town
    ROOM 2 101 My Street; My Town
    ROOM A 123 My Crescent; My Old Town
    ROOM A 12a My Avenue; My Very Old Town
    
    SELECT CAST('<x>' + REPLACE(addr, ' ', '</x><x>') + '</x>' AS XML).value('/x[3]', 'varchar(200)') from MyTable;
    
    从MyTable中选择CAST(''+REPLACE(addr','')+''作为XML);
    

    如何从第三个“”和第一个“;”中提取尽管如此?

    Joe J在评论中回答:


    如果您想在一个select语句中实现所有功能,可以使用CHARINDEX和SUBSTRING的可怕组合。像这样的

    select SUBSTRING(addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1,charindex(' ', addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1) - charindex(' ', addr, charindex(' ', addr, 1) + 1) -1) 
    
    将在第2和第3个“”之间获取您的号码

    谢谢@JoeJ-我如何将其修改为从第三个“;”到第一个“?”迈克尔

    @迈克尔

    select SUBSTRING(addr,charindex(' ', addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1) + 1,charindex(';', addr, 1) - charindex(' ', addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1) -1) will do between the third ' ' and the first ';'. 
    

    正如我所说,这非常可怕,而且严格依赖于每个记录中的空格等完全相同的位置。

    Joe J在评论中回答:


    如果您想在一个select语句中实现所有功能,可以使用CHARINDEX和SUBSTRING的可怕组合。像这样的

    select SUBSTRING(addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1,charindex(' ', addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1) - charindex(' ', addr, charindex(' ', addr, 1) + 1) -1) 
    
    将在第2和第3个“”之间获取您的号码

    谢谢@JoeJ-我如何将其修改为从第三个“;”到第一个“?”迈克尔

    @迈克尔

    select SUBSTRING(addr,charindex(' ', addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1) + 1,charindex(';', addr, 1) - charindex(' ', addr, charindex(' ', addr, charindex(' ', addr, 1) + 1) + 1) -1) will do between the third ' ' and the first ';'. 
    

    正如我所说,这是非常可怕的,而且严格依赖于空格等。在每个记录中都完全位于同一个位置。

    如果您的要求不会随时间发生太大变化,您可以这样严格地编程:

    with t as  (
    select 'ROOM 1 101 My Street; My Town' a union all
    select 'ROOM 2 101 My Street; My Town' a union all
    select 'ROOM A 123 My Crescent; My Old Town' a union all
    select 'ROOM A 12a My Avenue; My Very Old Town' a )
    , t2 as (
    select a, PATINDEX('% %', a) pi1, 
              PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) pi2, 
              PATINDEX('% %', SUBSTRING(a, 1 + PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) + nullif(PATINDEX('% %', a), 0), LEN(a))) pi3,
              PATINDEX('%;%', SUBSTRING(a, 1 + PATINDEX('% %', SUBSTRING(a, 1 + PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) + nullif(PATINDEX('% %', a), 0), LEN(a))) + PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) + nullif(PATINDEX('% %', a), 0), LEN(a))) pi4
      from t
    )
    select a, SUBSTRING(a, pi1, pi2) s1, SUBSTRING(a, pi1 + pi2, pi3) s2, SUBSTRING(a, pi1 + pi2 + pi3, pi4) s3, SUBSTRING(a, pi1 + pi2 + pi3 + pi4, len(a)) s4
     from t2
    
    它返回:

    如果您的需求不会随着时间的推移发生太多变化,您可以像这样严格地编程:

    with t as  (
    select 'ROOM 1 101 My Street; My Town' a union all
    select 'ROOM 2 101 My Street; My Town' a union all
    select 'ROOM A 123 My Crescent; My Old Town' a union all
    select 'ROOM A 12a My Avenue; My Very Old Town' a )
    , t2 as (
    select a, PATINDEX('% %', a) pi1, 
              PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) pi2, 
              PATINDEX('% %', SUBSTRING(a, 1 + PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) + nullif(PATINDEX('% %', a), 0), LEN(a))) pi3,
              PATINDEX('%;%', SUBSTRING(a, 1 + PATINDEX('% %', SUBSTRING(a, 1 + PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) + nullif(PATINDEX('% %', a), 0), LEN(a))) + PATINDEX('% %', SUBSTRING(a, 1 + nullif(PATINDEX('% %', a), 0), LEN(a))) + nullif(PATINDEX('% %', a), 0), LEN(a))) pi4
      from t
    )
    select a, SUBSTRING(a, pi1, pi2) s1, SUBSTRING(a, pi1 + pi2, pi3) s2, SUBSTRING(a, pi1 + pi2 + pi3, pi4) s3, SUBSTRING(a, pi1 + pi2 + pi3 + pi4, len(a)) s4
     from t2
    
    它返回:

    使用支持顺序位置的字符串拆分器(我建议使用
    DelimitedSplit8K_LEAD
    ),这是一个非常有用的方法。@Larnu我不确定我是否完全理解-这是SQL函数吗?是的,@Michael。如果您想在一个select语句中实现所有功能,可以使用
    CHARINDEX
    SUBSTRING
    的可怕组合。类似这样的
    select子字符串(addr,charindex(“”,addr,charindex(“”,addr,1)+1,charindex(“”,addr,charindex(“”,addr,charindex(“”,addr,1)+1)-charindex(“”,addr,charindex(“”,addr,1)+1)
    将获得第二个和第三个之间的数字。@Michael,
    select子字符串(addr,charindex)(“”,addr,charindex(“”,addr,charindex(“”,addr,1)+1)+1,charindex(“”,addr,1)-charindex(“”,addr,charindex(“”,addr,charindex(“”,addr,1)+1)-1)
    将在第三个“”和第一个“;”之间执行。正如我所说,这非常可怕,并且严格依赖于空格等。每个记录中的位置都完全相同。使用支持顺序位置的字符串拆分器(我建议使用
    DelimitedSplit8K_LEAD
    )这是一个可怕的组合。@Larnu我不确定我是否完全理解-这是一个SQL函数吗?是的,@Michael。如果你想在一个select语句中实现这一切,你可以使用
    CHARINDEX
    SUBSTRING
    。类似的
    选择子字符串(addr,CHARINDEX('',addr,CHARINDEX('',addr,1)+1,CHARINDEX)(“”,addr,charindex(“”,addr,charindex(“”,addr,1)+1)-charindex(“”,addr,charindex(“”,addr,1)+1)-1
    将获取第二个和第三个之间的数字。@Michael,
    选择子字符串(addr,charindex(“”,addr,charindex(“”,addr,charindex(“”,addr,1)+1),charindex(“”,addr,1)+1)-charindex(“”,addr,charindex(“”,addr,charindex(“”,addr,1)+1)+1)-1)
    将在第三个“”和第一个“;”。正如我所说,这非常可怕,并且严格依赖于空格等。在每个记录中都完全位于同一位置。