在SQL Server中拆分地址

时间:2016-05-09 08:40:02

标签: sql sql-server

我希望能够在SQL Server中拆分地址。我有一个示例地址

(10396 Whispering Pines Dr Frisco TX 75033-3807)

街道名称可能有多个名称,但邮政编码始终位于末尾,州位于旁边,然后是城市等...

我以为我会先切断拉链+4然后再向后工作(取下拉链并将其取下。然后获取状态(总是2位数)并将其移除然后移除城市。

其他一切都是街道地址。我上面包含的地址是它如何存储在数据库中。我自己尝试过,但我知道必须有更好的方法!

declare @streetAddress varchar(1500)
declare @zip varchar(10)
declare @state varchar(2)
declare @city varchar(250)

set @streetAddress = '10396 Whispering Pines Dr Frisco TX 75033-3807'

SET @streetAddress =  left(@streetAddress,charindex('-',@streetAddress) - 1)
SET @zip = right(@streetAddress,5)
SET @streetAddress = RTRIM(replace(@streetAddress,right(@streetAddress,5),''))
SET @state = right(@streetAddress,2)
SET @streetAddress = rtrim(replace(@streetAddress,right(@streetAddress,2),''))
SET @city = reverse(LEFT(reverse(@streetAddress),charindex(' ',@streetAddress)))
select @streetAddress,@state,@zip,@city

输出如下:

|10396 Whispering Pines Dr|TX|75033|Frisco|

2 个答案:

答案 0 :(得分:1)

尝试这样

DECLARE @test VARCHAR(100)='10396 Whispering Pines Dr Frisco TX 75033-3807';
DECLARE @testRev VARCHAR(100)=REVERSE(@test);
DECLARE @pos1 INT=CHARINDEX(' ',@testRev);
DECLARE @pos2 INT=CHARINDEX(' ',@testRev,@pos1+1);
DECLARE @pos3 INT=CHARINDEX(' ',@testRev,@pos2+1); 

DECLARE @part4 VARCHAR(100)=REVERSE(LEFT(@testRev,@pos1-1));
DECLARE @part3 VARCHAR(100)=REVERSE(SUBSTRING(@testRev,@pos1+1,@pos2-@pos1));
DECLARE @part2 VARCHAR(100)=REVERSE(SUBSTRING(@testRev,@pos2+1,@pos3-@pos2));
DECLARE @part1 VARCHAR(100)= REVERSE(SUBSTRING(@testRev,@pos3,1000));

SELECT @part1, @part3,@part4,@part2

结果

10396 Whispering Pines Dr    TX     75033-3807   Frisco

编辑:另一种方法

这种方法的优点是,可以一次性获取所有部件(由空白分隔)。这样可以更容易地继续解决多字问题的任何逻辑......

DECLARE @test VARCHAR(100)='10396 Whispering Pines Dr Frisco TX 75033-3807';
DECLARE @testRev VARCHAR(100)=REVERSE(@test);

DECLARE @casted XML=(SELECT CAST('<x>' + REPLACE(@testRev,' ','</x><x>')+'</x>' AS XML));

SELECT REVERSE(@casted.value('/x[1]','varchar(max)')) AS ZIP
      ,REVERSE(@casted.value('/x[2]','varchar(max)')) AS State
      ,REVERSE(@casted.value('/x[3]','varchar(max)')) AS City
      ,ISNULL(REVERSE(@casted.value('/x[9]','varchar(max)')) + ' ','')
      +ISNULL(REVERSE(@casted.value('/x[8]','varchar(max)')) + ' ','')    
      +ISNULL(REVERSE(@casted.value('/x[7]','varchar(max)')) + ' ','')
      +ISNULL(REVERSE(@casted.value('/x[6]','varchar(max)')) + ' ','')    
      +ISNULL(REVERSE(@casted.value('/x[5]','varchar(max)')) + ' ','')    
      +ISNULL(REVERSE(@casted.value('/x[4]','varchar(max)')) + ' ','') AS TheRest  

答案 1 :(得分:0)

如果城市名称中有空格,那么几乎不可能进行锻炼,这里提出的建议基于查询表和来自http://www.geonames.org的一些参考数据(我可以& #39; t保证此来源的完整性)

CREATE TABLE PostReference
    (
     CountryCode CHAR(2)
    ,PostalCode CHAR(5)
    ,PlaceName VARCHAR(180)
    ,AdminName1 VARCHAR(100)
    ,AdminCode1 VARCHAR(20)
    ,AdminName2 VARCHAR(100)
    ,AdminCode2 VARCHAR(20)
    ,AdminName3 VARCHAR(100)
    ,AdminCode3 VARCHAR(20)
    ,Latitude DECIMAL(7, 4)
    ,Longitude DECIMAL(7, 4)
    ,Accuracy CHAR(1)
    );
GO

BULK INSERT PostReference
FROM 'D:\US\US.txt'
WITH (FIELDTERMINATOR = '\t',ROWTERMINATOR = '0x0a');
GO

然后是一个(不太理想的)查询 - 我相信你可以改进这个。

DECLARE @Address VARCHAR(100) = '10396 Whispering Pines Dr Frisco TX 75033-3807'
SELECT 
    LEFT(@Address, CHARINDEX(PlaceName, @Address) - 1) StreetAddress
    ,PlaceName
    ,AdminCode1 State
    ,RIGHT(@Address, LEN(@Address) - CHARINDEX(PostalCode, @Address) + 1) ZipCode
FROM PostReference
WHERE @Address LIKE '%' + PlaceName + ' ' + AdminCode1 + ' ' + PostalCode+'%'


StreetAddress                        PlaceName       State  ZipCode
------------------------------------ --------------- ------ -----------
10396 Whispering Pines Dr            Frisco          TX     75033-3807

(1 row(s) affected)

希望这是有用的。