Sql server 格式化地址字符串
使用T-SQL,我需要知道将包含地址的字符串拆分为单独字段的最佳方法,以便重新格式化它们。它必须能够处理不同的输入格式Sql server 格式化地址字符串,sql-server,tsql,Sql Server,Tsql,使用T-SQL,我需要知道将包含地址的字符串拆分为单独字段的最佳方法,以便重新格式化它们。它必须能够处理不同的输入格式 AddressIn: AddressOut: StreetNumber: StreetName: '25 Main Street' | '25' 'Main Street' '25 MainStreet' | '25' 'MainStreet' '
AddressIn: AddressOut:
StreetNumber: StreetName:
'25 Main Street' | '25' 'Main Street'
'25 MainStreet' | '25' 'MainStreet'
'Main Street 25' | '25' 'Main Street'
'MainStreet 25' | '25' 'MainStreet'
'25B Main Street' | '25B' 'Main Street'
'25B MainStreet' | '25B' 'MainStreet'
'Main Street 25B' | '25B' 'Main Street'
'MainStreet 25B' | '25B' 'MainStreet'
任何帮助都将不胜感激。这将满足您的要求,但我同意上面的评论,使用SQL进行此类解析并不理想
select
CASE
WHEN patindex('%[0-9]%',theAddress)=1
THEN substring(theaddress,1,charindex(' ',theaddress) )
ELSE rtrim(substring(theAddress,patindex('%[0-9]%',theAddress),99) )
END as StreetNumber,
CASE
WHEN patindex('%[0-9]%',theAddress)=1
THEN substring(theaddress,charindex(' ',theAddress)+1,99)
ELSE substring(theAddress,1,patindex('%[0-9]%',theAddress)-1)
END as StreetName
FROM <yourtable>
选择
案例
当patindex('%[0-9]]'时,地址=1
然后是子字符串(地址,1,charindex(“”,地址))
ELSE rtrim(子字符串(地址,patindex('%[0-9]]',地址),99))
以街号结束,
案例
当patindex('%[0-9]]'时,地址=1
然后是子字符串(地址,charindex('',地址)+1,99)
ELSE子字符串(地址,1,patindex('%[0-9]',地址)-1)
以StreetName结尾
从…起
注意事项,您可以从评论中看到
- 性能将不是很好,尤其是如果您的桌子是 大的李>
- 除示例之外的其他地址格式可能会中断 代码
'25B'主街'
步骤2:(步骤1是主要思想,也是最重要的,下面的函数只是为了使选择更容易-函数可能不同,可以用不同的方式编写)
然后
最后是这个查询:select*from dbo.splitAddress_2()
结果:
注意:数字部分是否位于地址字符串的开头、中间或结尾并不重要,例如对于“Main 25B Street”
此解决方案将运行良好
对@Sparky的答案进行了鲁棒性修改
DECLARE @Addresses TABLE (Address NVARCHAR(200))
INSERT INTO @Addresses VALUES
('25 Main Street'),
('25 MainStreet'),
('Main Street 25'),
('MainStreet 25'),
('25B Main Street'),
('25B MainStreet'),
('Main Street 25B'),
('MainStreet 25B')
select
CASE
WHEN patindex('%[0-9]%',Address)=1
THEN substring(Address,1,charindex(' ',Address) )
ELSE rtrim(substring(Address,patindex('%[0-9]%',Address),99) )
END as StreetNumber,
CASE
WHEN patindex('%[0-9]%',Address)=1
THEN REPLACE(Address,substring(Address,1,charindex(' ',Address) ),'')
ELSE REPLACE(Address,rtrim(substring(Address,patindex('%[0-9]%',Address),99) ),'')
END as StreetName
FROM @Addresses
据推测,这段代码应该能够更好地处理更多类型的地址
此版本是一个额外的例外:
DECLARE @Addresses TABLE (Address NVARCHAR(200))
INSERT INTO @Addresses VALUES
('25 Main Street'),
('25 MainStreet'),
('Main Street 25'),
('MainStreet 25'),
('25B Main Street'),
('25B MainStreet'),
('Main Street 25B'),
('MainStreet 25B'),
('Main 25B Street')
select
CASE
WHEN CHARINDEX(' ',Address,patindex('%[0-9]%',Address))-patindex('%[0-9]%',Address) > 0
THEN substring(Address, patindex('%[0-9]%',Address), CHARINDEX(' ',Address,patindex('%[0-9]%',Address))-patindex('%[0-9]%',Address))
WHEN patindex('%[0-9]%',Address)=1
THEN substring(Address,1,charindex(' ',Address) )
ELSE rtrim(substring(Address,patindex('%[0-9]%',Address),99) )
END as StreetNumber,
CASE
WHEN CHARINDEX(' ',Address,patindex('%[0-9]%',Address))-patindex('%[0-9]%',Address) > 0
THEN REPLACE(Address,substring(Address, patindex('%[0-9]%',Address), CHARINDEX(' ',Address,patindex('%[0-9]%',Address))-patindex('%[0-9]%',Address)),'')
WHEN patindex('%[0-9]%',Address)=1
THEN REPLACE(Address,substring(Address,1,charindex(' ',Address) ),'')
ELSE REPLACE(Address,rtrim(substring(Address,patindex('%[0-9]%',Address),99) ),'')
END as StreetName
FROM @Addresses
完全避免使用SQL,看看是否可以从应用程序代码中执行此操作!我认为您会发现,定义可靠地标识任意地址字符串的特定组件所需的规则非常困难。如果不能用通俗易懂的英语定义规则,那么就很难用SQL编写代码:)恐怕不行。我从一个附在供应商应用程序上的数据库中提取数据&它只存储为字符串。我以前有过这种情况,数据来自呼叫中心,来自自由文本表单。我建议您选择地址,并将一致的数据存储在本地数据库中。由于有数百万行采用邮政编码格式,您将无法逃脱为每行执行的拆分字符串函数调用。旁注:我看不出有任何理由尝试这样的操作。地址有很多种味道,所以尝试以任何方式格式化它们几乎是无用的。请参阅使用此方法的第一部分(获取街道编号),这一部分更加清晰,只需用空字符串替换当前记录中已精简的街道编号,即可以更可靠的方式获得街道名称。对获取街道编号的方法进行更广泛的测试并加以完善,将无需使用第二种方法获取街道名称。我同意,但是您需要提取街道编号,将其存储在某个位置,并在随后的街道名称部分使用替换。这是可行的,但会使查询更加复杂。以上是一个与他已知的地址格式相匹配的简单解决方案。不完美,但使用非常简单抱歉,只需检查它的
Main 25B Street
输出不正确Main 25B Street不在ops示例地址格式中。。。ops声明,原始请求中的变化是唯一预期的输入格式,这是另一种方法。谢谢。很抱歉,只是检查一下主25B街的输出是否正确。首先,我从未声称我修改的代码处理了所有异常,说“错”,我说它更健壮。请阅读代码之外的英语句子。第二,这种格式是极端的,我不相信普通人会写它,但它肯定是“可修复的”,只需要一点额外的代码。是的,我非常同意,起初,我还试图用这种格式编写函数,但在发布之前对其进行了更改,因为它需要更多的检查和检查。我编写了一个版本来处理这个额外的异常,以便查看它的外观:)如果可能,请始终尝试避免while循环和游标,对于这种解决方案,您的方法甚至效率更低。@SubqueryCrunch我确信在这种情况下,一个小循环比在case
中使用大量的内置函数
和多个语句
时更好,无论如何,谢谢您的评论,祝您好运。
CREATE TABLE address_table (AddressIn NVARCHAR(200))
INSERT INTO address_table VALUES
('25 Main Street'),
('25 MainStreet'),
('Main Street 25'),
('MainStreet 25'),
('25B Main Street'),
('25B MainStreet'),
('Main Street 25B'),
('MainStreet 25B'),
('Main 25B Street')
CREATE FUNCTION [dbo].[splitAddress_2]()
RETURNS @output TABLE(street_number NVARCHAR(50),street_name NVARCHAR(100))
BEGIN
DECLARE @adr varchar(200)
DECLARE cr CURSOR
FOR SELECT AddressIn FROM address_table
OPEN cr
FETCH NEXT FROM cr into @adr;
while(@@fetch_status=0)
begin
insert into @output(street_number,street_name)
select * from dbo.splitAddress_1(@adr)
FETCH NEXT FROM cr into @adr;
end
close cr
deallocate cr
RETURN
END
DECLARE @Addresses TABLE (Address NVARCHAR(200))
INSERT INTO @Addresses VALUES
('25 Main Street'),
('25 MainStreet'),
('Main Street 25'),
('MainStreet 25'),
('25B Main Street'),
('25B MainStreet'),
('Main Street 25B'),
('MainStreet 25B')
select
CASE
WHEN patindex('%[0-9]%',Address)=1
THEN substring(Address,1,charindex(' ',Address) )
ELSE rtrim(substring(Address,patindex('%[0-9]%',Address),99) )
END as StreetNumber,
CASE
WHEN patindex('%[0-9]%',Address)=1
THEN REPLACE(Address,substring(Address,1,charindex(' ',Address) ),'')
ELSE REPLACE(Address,rtrim(substring(Address,patindex('%[0-9]%',Address),99) ),'')
END as StreetName
FROM @Addresses
DECLARE @Addresses TABLE (Address NVARCHAR(200))
INSERT INTO @Addresses VALUES
('25 Main Street'),
('25 MainStreet'),
('Main Street 25'),
('MainStreet 25'),
('25B Main Street'),
('25B MainStreet'),
('Main Street 25B'),
('MainStreet 25B'),
('Main 25B Street')
select
CASE
WHEN CHARINDEX(' ',Address,patindex('%[0-9]%',Address))-patindex('%[0-9]%',Address) > 0
THEN substring(Address, patindex('%[0-9]%',Address), CHARINDEX(' ',Address,patindex('%[0-9]%',Address))-patindex('%[0-9]%',Address))
WHEN patindex('%[0-9]%',Address)=1
THEN substring(Address,1,charindex(' ',Address) )
ELSE rtrim(substring(Address,patindex('%[0-9]%',Address),99) )
END as StreetNumber,
CASE
WHEN CHARINDEX(' ',Address,patindex('%[0-9]%',Address))-patindex('%[0-9]%',Address) > 0
THEN REPLACE(Address,substring(Address, patindex('%[0-9]%',Address), CHARINDEX(' ',Address,patindex('%[0-9]%',Address))-patindex('%[0-9]%',Address)),'')
WHEN patindex('%[0-9]%',Address)=1
THEN REPLACE(Address,substring(Address,1,charindex(' ',Address) ),'')
ELSE REPLACE(Address,rtrim(substring(Address,patindex('%[0-9]%',Address),99) ),'')
END as StreetName
FROM @Addresses