用多个分隔符分割字符串

时间:2012-07-25 20:16:35

标签: sql sql-server sql-server-2008 tsql

我有一组地址:

34 Main St Suite 23
435 Center Road Ste 3
34 Jack Corner Bldg 4
2 Some Street Building 345

分界符将是:

Suite, Ste, Bldg, Building

我想将这些地址分成address1address2,如下所示:

+---------------------+--------------+
|      Address1       |   Address2   |
+---------------------+--------------+
| 34 Main St          | Suite 23     |
| 435 Center Road     | Ste 3        |
| 34 Jack Corner      | Bldg 4       |
| 2 Some Street       | Building 345 |
+---------------------+--------------+

如何以这种方式定义一组分隔符和分隔符?

4 个答案:

答案 0 :(得分:4)

SELECT
   T.Address,
   Left(T.Address, IsNull(X.Pos - 1, 2147483647)) Address1,
   Substring(T.Address, X.Pos + 1, 2147483647) Address2 -- Null if no second
FROM
   (
      VALUES
      ('34 Main St Suite 23'),
      ('435 Center Road Ste 3'),
      ('34 Jack Corner Bldg 4'),
      ('2 Some Street Building 345'),
      ('123 Sterling Rd'),
      ('405 29th St Bldg 4 Ste 217')
   ) T (Address)
   OUTER APPLY (
      SELECT TOP 1 NullIf(PatIndex(Delimiter, T.Address), 0) Pos
      FROM (
         VALUES ('% Suite %'), ('% Ste %'), ('% Bldg %'), ('% Building %')
      ) X (Delimiter)
      WHERE T.Address LIKE X.Delimiter 
      ORDER BY Pos
   ) X

我使用PatIndex()所以像“Sterling Rd”这样的地址不会在“Ste”上给你一个错误的匹配

结果集:

Address1         Address2
---------------  --------
34 Main St       Suite 23
435 Center Road  Ste 3
34 Jack Corner   Bldg 4
2 Some Street    Building 345
123 Sterling Rd  NULL
405 29th St      Bldg 4 Ste 217

答案 1 :(得分:1)

您可以使用分隔符表来执行拆分。在这个例子中,我使用XML来进行解析,但是在你用可靠的分隔符代替你的集合(Ste,Suite等)之后,你可以使用任何基于t-sql的方法执行拆分。

declare @tab table (s varchar(100))
insert into @tab
    select '34 Main St Suite 23' union all
    select '435 Center Road Ste 3' union all
    select '34 Jack Corner Bldg 4' union all
    select '2 Some Street Building 345' union all
    select '20950 N. Tatum Blvd., Ste 300' union all
    select '1524 McHenry Ave Ste 470';

declare @delimiters table (d varchar(100));
insert into @delimiters
    select 'Suite' union all
    select 'Ste' union all
    select 'Bldg' union all
    select 'Building';

select  s, 
        cast('<r>'+ replace(s, d, '</r><r>'+d) + '</r>' as xml),
        [Street1] = cast('<r>'+ replace(s, d, '</r><r>'+d) + '</r>' as xml).value('r[1]', 'varchar(100)'),
        [Street2] = cast('<r>'+ replace(s, d, '</r><r>'+d) + '</r>' as xml).value('r[2]', 'varchar(100)')
from    @tab t
cross
apply   @delimiters d 
where   charindex(' '+d+' ', s) > 0;

答案 2 :(得分:1)

select Addr,CASE WHEN CHARINDEX('suite',addr,1)>0 then LEFT(addr,CHARINDEX('suite',addr,1)-1)
            WHEN CHARINDEX('Ste',addr,1)>0 then LEFT(addr,CHARINDEX('Ste',addr,1)-1) 
            WHEN CHARINDEX('Bldg',addr,1)>0 then LEFT(addr,CHARINDEX('Bldg',addr,1)-1)
            WHEN CHARINDEX('Building',addr,1)>0 then LEFT(addr,CHARINDEX('Building',addr,1)-1)
            END as [Address],

            CASE WHEN CHARINDEX('suite',addr,1)>0 then RIGHT(addr,len(addr)-(CHARINDEX('suite',addr,1)-1))
            WHEN CHARINDEX('Ste',addr,1)>0 then RIGHT(addr,len(addr)-(CHARINDEX('Ste',addr,1)-1))
            WHEN CHARINDEX('Bldg',addr,1)>0 then RIGHT(addr,len(addr)-(CHARINDEX('Bldg',addr,1)-1))
            WHEN CHARINDEX('Building',addr,1)>0 then RIGHT(addr,len(addr)-(CHARINDEX('Building',addr,1)-1))
            END as [Address1]

 from Addr

答案 3 :(得分:-1)

如果您打算尝试解析这些数据,并且它不会被某些东西(即逗号)分隔,那么它将变得更加困难,您将不得不做出一些假设。拥有更大的数据集可以帮助您做出更强的假设,但它仍然会非常脆弱。

查看您的数据,我认为您可以做出以下假设: 1)地址2始终是最后2个单词(当用空格分割时),因此您可以根据空格分割地址,并将最后2个用作地址2,其余用作地址1。 2)您可以假设地址1是前3个字,其余是地址2。

要分割这些数据,我要么使用T-SQL等价的split('',$ data)来获取单词数组。或者,使用等效于strpos和strrpos的T-SQL来查找倒数第二个空格,或第三个空格的位置,并将之前和之后的所有内容都包含在适当的变量中。

由您根据可用数据做出决定,以选择更强大的假设并与之合作。

相关问题