假设我有下表:
AAAAAA
AAAAAB
CCCCCC
我如何制作一个让我知道AAAAA
和AAAAB
相似的查询(因为它们共享五个字符)?理想情况下,我想把它写成一个查询,检查两个字段是否在字符串中的任何位置共享五个字符,但这似乎超出了SQL的范围,我应该写入C#应用程序?
理想情况下,查询会添加另一列显示:Similar to 'AAAAA', 'AAAAB'
答案 0 :(得分:7)
我建议你不要试图通过引入多值属性来违反1NF。
注意到SUBSTRING
非常便携:
WITH T
AS
(
SELECT *
FROM (
VALUES ('AAAAAA'),
('AAAAAB'),
('CCCCCC')
) AS T (data_col)
)
SELECT T1.data_col,
T2.data_col AS data_col_similar_to
FROM T AS T1, T AS T2
WHERE T1.data_col < T2.data_col
AND SUBSTRING(T1.data_col, 1, 5)
= SUBSTRING(T2.data_col, 1, 5);
Alternativvely:
T1.data_col LIKE SUBSTRING(T2.data_col, 1, 5) + '%';
答案 1 :(得分:3)
这将找到所有匹配项,也就是在单词中间的那些匹配项,它在大桌面上表现不佳
declare @t table(a varchar(20))
insert @t select 'AAAAAA'
insert @t select 'AAAAAB'
insert @t select 'CCCCCC'
insert @t select 'ABCCCCC'
insert @t select 'DDD'
declare @compare smallint = 5
;with cte as
(
select a, left(a, @compare) suba, 1 h
from @t
union all
select a, substring(a, h + 1, @compare), h+1
from cte where cte.h + @compare <= len(a)
)
select t.a, cte.a match from @t t
-- if you don't want the null matches, remove the 'left' from this join
left join cte on charindex(suba, t.a) > 0 and t.a <> cte.a
group by t.a, cte.a
结果:
a match
-------------------- ------
AAAAAA AAAAAB
AAAAAB AAAAAA
ABCCCCC CCCCCC
CCCCCC ABCCCCC
答案 2 :(得分:2)
您可以使用left来比较前五个字符,并且可以使用for xml path
将类似的字符串连接到一列。
declare @T table
(
ID int identity primary key,
Col varchar(10)
)
insert into @T values
('AAAAAA'),
('AAAAAB'),
('AAAAAC'),
('CCCCCC')
select Col,
stuff((select ','+T2.Col
from @T as T2
where left(T1.Col, 5) = left(T2.Col, 5) and
T1.ID <> T2.ID
for xml path(''), type).value('.', 'varchar(max)'), 1, 1, '') as Similar
from @T as T1
结果:
Col Similar
---------- -------------------------
AAAAAA AAAAAB,AAAAAC
AAAAAB AAAAAA,AAAAAC
AAAAAC AAAAAA,AAAAAB
CCCCCC NULL