我有一个存储过程,它从“1 Spooner Street”之类的列中提取地址,但我需要缩写“Street”、“Apartment”等。
我知道我可以为每种情况将列名包装在 REPLACE 中,但我想知道是否有不同的方法可以做到这一点。
有任何想法吗?提示?
我有一个存储过程,它从“1 Spooner Street”之类的列中提取地址,但我需要缩写“Street”、“Apartment”等。
我知道我可以为每种情况将列名包装在 REPLACE 中,但我想知道是否有不同的方法可以做到这一点。
有任何想法吗?提示?
一个可能可行的建议是创建一个包含您要用于替换的所有值的表,类似于以下内容:
create table replacements
(
id int identity primary key,
orig_value varchar(50) not null,
new_value varchar(50) not null
);
insert into replacements values
('Street', 'St'),
('Drive', 'Dr'),
('Boulevard', 'Blvd'),
('Apartment', 'Apt');
然后,您可以将此替换表加入您的主表并使用REPLACE()
. 一些样本数据:
create table addresses
(
id int identity primary key,
addr1 varchar(100) not null
);
insert into addresses values
('123 Main Street'),
('235 Blah Boulevard'),
('78 E Test Drive'),
('78 E Multiple Lane Apartment 23');
最后,您可以创建一个函数,该函数可用于将值替换为表中存在的值。函数脚本:
create function replace_name
(
@orig_value varchar(50)
)
returns varchar(50)
AS
BEGIN
declare @new_address varchar(50)
declare @i int = 0
declare @totalReplacements int
set @totalReplacements = (select COUNT(*)
from dbo.replacements r
where @orig_value like '%'+r.orig_value+'%')
set @new_address = @orig_value
if @totalReplacements > 0
begin
while @i < @totalReplacements
begin
set @new_address = (select top 1 replace(@new_address, r.orig_value, r.new_value)
from dbo.replacements r
where @new_address like '%'+r.orig_value+'%')
if @i <= @totalReplacements
set @i = @i + 1
end
end
else
begin
set @new_address = @orig_value;
end
return @new_address;
END
然后在查询数据时,将地址传递给函数:
select a.id,
a.addr1,
dbo.replace_name(a.addr1) newAddress
from dbo.addresses a;
请参阅SQL Fiddle with Demo。这将给出结果:
| ID | ADDR1 | NEWADDRESS |
-------------------------------------------------------------------
| 1 | 123 Main Street | 123 Main St |
| 2 | 235 Blah Boulevard | 235 Blah Blvd |
| 3 | 78 E Test Drive | 78 E Test Dr |
| 4 | 57 E Multiple Drive Apartment 23 | 57 E Multiple Dr Apt 23 |
| 5 | 19 E none | 19 E none |
另一个想法(无代码)是创建另一个包含两个字符串的表 - 一个用于完整单词,一个用于缩写。
然后在您的过程中,循环这些条目,在原始记录中搜索完整的单词,并用缩写替换。
这样,代码将更短且更易于阅读 - 当您需要向列表中添加一个缩写词时,行为将由数据驱动而不是硬编码。