我在SQL Server 2012中工作。在我的表中,有一个名为St_Num
的列,其数据如下:
St_Num status
------------------------------
128 TIMBER RUN DR EXP
128 TIMBER RUN DRIVE EXP
现在我们可以注意到上面的数据存在拼写错误。我想要做的是,如果在这种情况下数字128和St_Num
列中的前3个字母相同,那么这两行应该被认为是相同的,输出应该是:
St_Num status
-----------------------------
128 TIMBER RUN DR EXP
我对此做了一些搜索,发现左边或子字符串函数在这里很方便,但我不知道它们将如何用于获取我需要的内容,即使它们可以解决我的问题也不知道。任何关于如何获得所需输出的帮助都会很棒。
这将只输出第一个匹配的行:
with cte as (
select *,
row_number() over (order by (select null)) rn
from tablename
)
select St_Num, status from cte t
where not exists (
select 1 from cte
where
left(St_Num, 7) = left(t.St_Num, 7)
and
rn < t.rn
)
见demo
这可以通过使用子查询来完成,就像消除表中的重复项一样:
SELECT Str_Num, status
FROM <your_table> a
WHERE NOT EXISTS (SELECT 1
FROM <your_table> b
WHERE SUBSTRING(b.Str_Num, 1, 7) = SUBSTRING(a.Str_Num, 1, 7));
但是,如果数字保证为3个字符长,或者如果您不介意在数字少于字符的情况下占用更多字符,则此方法才有效。
您可以使用status
和substring(St_Num,1,3)
进行分组
with t(St_Num, status) as
(
select '128 TIMBER RUN DR' ,'EXP' union all
select '128 TIMBER RUN DRIVE','EXP'
)
select min(St_Num) as St_Num, status
from t
group by status, substring(St_Num,1,3);
St_Num status
----------------- ------
128 TIMBER RUN DR EXP
我并不赞同你的匹配逻辑。 。 。但这不是你的问题。最大的问题是字符串前面的数字有多长。因此,您可以使用以下内容获取最短的地址:
select distinct t.*
from t
where not exists (select 1
from t t2
where left(t2.st_num, patindex('%[a-zA-Z]%') + 2, t.st_num) = left(t.st_num, patindex('%[a-zA-Z]%', t.st_num) + 2) and
len(t.St_Num) < len(t2.St_Num)
);
我仍然有一种奇怪的感觉,你的标准不足以匹配相同的地址,但这可能有所帮助,因为它也考虑了数字的长度:
WITH ParsedAddresses(st_num, exp, number)
AS
(
SELECT st_num,
exp,
number = ROW_NUMBER() OVER(PARTITION BY LEFT(st_num, CHARINDEX(' ', st_num) + 3) ORDER BY LEN(st_num))
FROM <table_name>
)
SELECT st_num, exp FROM ParsedAddresses
WHERE number = 1