我希望能够在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|
像这样尝试
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
由于如果城市名称中有空格,几乎不可能锻炼,因此以下是基于查找表和一些参考数据的建议http://www.geonames.org(我不能保证这个来源的完整性)
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:USUS.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)
希望这个有用。