Search code examples
sqlsql-serversql-server-2008t-sqlsql-server-2014

Split Address field


I have a address column that contains street address along with the PO Box no.I would like to extract street address and postcode into a separate column, how can I do that?

Sample Data

     1 ABC CDE PO BOX 650
       15 N. MAIN STREET P.O. BOX 009
       (ABC)PO BOX 5909 
        1 TAKEWAY PLAZA          
       PO BOX 146012  Parkway STREET

DESIRED OUTPUT:-

STREET ADDRESS               ADDRESS2


  1 ABC CDE                    P.O. BOX 650
  15 N. MAIN STREET            P.O. BOX 009
  ABC                          P.O. BOX 5909
  1 TAKEWAY PLAZA
  Parkway STREET               P.O. BOX 146012

Solution

  • Parsing addresses can be a slippery slope. That said, you seem to be keying off of PO Box, so that makes it a little more managable,

    That said, you may want to consider using the GOOGLE API to normaize your address Address standardization within a database

    This will produce the desired results by normalizing and cleaning the string. Then it is a simple matter of parsing the string, and then reconstructing it via XML and Stuff().

    There are many parse/split functions available, I did provide mine below

    Example

    Declare @YourTable table (address varchar(250))
    Insert Into @YourTable values
    ('1 ABC CDE PO BOX 650'),
    ('15 N. MAIN STREET P.O. BOX 009'),
    ('(ABC)PO BOX 5909'),
    ('1 TAKEWAY PLAZA'),          
    ('PO BOX 146012  Parkway STREET')
    
    Select A.*
          ,C.*
     From  @YourTable A
     Cross Apply (
                   Select CleanString = replace(replace(replace(replace(replace(replace(replace(A.Address,'  ',' '),'P. O','P.O'),'P.','P'),'O. ','O'),'O BOX','OBOX'),'BOX ','BOX'),'POBOX',' POBOX')+' '
                 ) B
     Outer Apply (
                    Select Address1 = Stuff((Select ' ' +RetVal 
                                             From  [dbo].[udf-Str-Parse](B.CleanString,' ')
                                             Where RetVal Not Like 'POBOX%'
                                             For XML Path ('')),1,1,'')
                          ,Address2 = (Select replace(RetVal,'POBOX','P.O. Box ') From  [dbo].[udf-Str-Parse](B.CleanString,' ') Where RetVal Like 'POBOX%')
                 ) C
    

    Returns

    address                         Address1            Address2
    1 ABC CDE PO BOX 650            1 ABC CDE           P.O. Box 650
    15 N. MAIN STREET P.O. BOX 009  15 N. MAIN STREET   P.O. Box 009
    (ABC)PO BOX 5909                (ABC)               P.O. Box 5909
    1 TAKEWAY PLAZA                 1 TAKEWAY PLAZA     NULL
    PO BOX 146012  Parkway STREET   Parkway STREET      P.O. Box 146012
    

    The UDF if Interested

    CREATE FUNCTION [dbo].[udf-Str-Parse] (@String varchar(max),@Delimiter varchar(10))
    Returns Table 
    As
    Return (  
        Select RetSeq = Row_Number() over (Order By (Select null))
              ,RetVal = LTrim(RTrim(B.i.value('(./text())[1]', 'varchar(max)')))
        From  (Select x = Cast('<x>' + replace((Select replace(@String,@Delimiter,'§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml).query('.')) as A 
        Cross Apply x.nodes('x') AS B(i)
    );
    --Thanks Shnugo for making this XML safe
    --Select * from [dbo].[udf-Str-Parse]('Dog,Cat,House,Car',',')
    --Select * from [dbo].[udf-Str-Parse]('John Cappelletti was here',' ')
    --Select * from [dbo].[udf-Str-Parse]('this,is,<test>,for,< & >',',')