我正在使用SQL Server2012。在我的表中,有一个名为St_Num
的列,其数据如下:
St_Num status
------------------------------
128 TIMBER RUN DR EXP
128 TIMBER RUN DRIVE EXP
现在,我们可以注意到上面的数据中存在拼写差异。我想做的是,如果在这种情况下St_Num
列中的128个数字和前3个字母相同,则应该将这两行视为相同,这样输出应该是:
St_Num status
-----------------------------
128 TIMBER RUN DR EXP
我对此进行了一些搜索,发现left或substring函数在这里可以派上用场,但我不知道如何在这里使用它们来获得我所需要的东西,即使它们可以解决我的问题也不知道。关于如何获得所需输出的任何帮助都将非常有用。
答案 0 :(得分:1)
这可以通过使用子查询来完成,其方式与消除表中的重复项相同,因此:
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个字符的情况下,或者如果您不介意在数字较少的情况下占用更多字符的情况下,这才起作用。
答案 1 :(得分:1)
这将仅输出匹配的第一行:
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
答案 2 :(得分:1)
您可以按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
答案 3 :(得分:1)
我不太赞成您的匹配逻辑。 。 。但这不是你的问题。最大的问题是字符串前的数字多长时间。因此,您可以使用以下方法获得最短的地址:
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)
);
答案 4 :(得分:0)
我仍然感到奇怪,您的条件不足以匹配相同的地址,但这可能会有所帮助,因为它还会考虑数字的长度:
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