客户号| 序号|字段一|字段二
A|10001|ss|dd
B|10002|aa|cc
C|10003|ss|aa
D|10004|bb|cc
E|10005|zz|aa
-----------------
结果
A|10001|ss|dd 10001
B|10002|aa|cc 10002
C|10003|ss|aa 10001
D|10004|bb|cc 10002
E|10005|zz|aa 10005比如有五个唯一客户号,
假如A的客户与C的客户别有相似点,
即将A、C认为是同一个客户;接下来B开始搜索比对时
,就不再和C比对
A|10001|ss|dd
B|10002|aa|cc
C|10003|ss|aa
D|10004|bb|cc
E|10005|zz|aa
-----------------
结果
A|10001|ss|dd 10001
B|10002|aa|cc 10002
C|10003|ss|aa 10001
D|10004|bb|cc 10002
E|10005|zz|aa 10005比如有五个唯一客户号,
假如A的客户与C的客户别有相似点,
即将A、C认为是同一个客户;接下来B开始搜索比对时
,就不再和C比对
SOUNDEX
返回由四个字符组成的代码 (SOUNDEX) 以评估两个字符串的相似性。语法
SOUNDEX ( character_expression ) 参数
character_expression是字符数据的字母数字表达式。character_expression 可以是常数、变量或列。返回类型
char注释
SOUNDEX 将 alpha 字符串转换成由四个字符组成的代码,以查找相似的词或名称。代码的第一个字符是 character_expression 的第一个字符,代码的第二个字符到第四个字符是数字。将忽略 character_expression 中的元音,除非它们是字符串的第一个字母。可以嵌套字符串函数。示例
下例显示 SOUNDEX 函数及相关的 DIFFERENCE 函数。在第一个示例中,返回所有辅音字母的标准 SOUNDEX 值。为 Smith 和 Smythe 返回的 SOUNDEX 结果相同,因为不包括所有元音、字母 y、连写字母和字母 h。-- Using SOUNDEX
SELECT SOUNDEX ('Smith'), SOUNDEX ('Smythe')下面是结果集:----- -----
S530 S530 (1 row(s) affected)DIFFERENCE 函数比较 SOUNDEX 模式结果的差。第一个示例显示两个仅元音不同的字符串。返回的差是 4(可能的最小差)。-- Using DIFFERENCE
SELECT DIFFERENCE('Smithers', 'Smythers')
GO下面是结果集:-----------
4 (1 row(s) affected)在下例中,字符串的辅音不同,所以返回的差是 2(较高的差)。SELECT DIFFERENCE('Anothers', 'Brothers')
GO下面是结果集:-----------
2 (1 row(s) affected)
create table tb(客户号 varchar(10), 序号 varchar(10),字段一 varchar(10), 字段二 varchar(10))
insert into tb values('A','10001','ss','dd')
insert into tb values('B','10002','aa','cc')
insert into tb values('C','10003','ss','aa')
insert into tb values('D','10004','bb','cc')
insert into tb values('E','10005','zz','aa')
goselect m.* , n.序号 序号2 from tb m, (select min(序号) 序号 , 字段一 from tb group by 字段一 having count(1) > 1) n where m.字段一 = n.字段一
union all
select m.* , n.序号 序号2 from tb m, (select min(序号) 序号 , 字段二 from tb group by 字段二 having count(1) > 1) n where m.字段二 = n.字段二 and m.字段二 not in
(select m.字段二 from tb m, (select min(序号) 序号 , 字段一 from tb group by 字段一 having count(1) > 1) n where m.字段一 = n.字段一)
union all
select * , 序号 序号2 from tb where 客户号 not in
(
select m.客户号 from tb m, (select min(序号) 序号 , 字段一 from tb group by 字段一 having count(1) > 1) n where m.字段一 = n.字段一
union all
select m.客户号 from tb m, (select min(序号) 序号 , 字段二 from tb group by 字段二 having count(1) > 1) n where m.字段二 = n.字段二 and m.字段二 not in
(select m.字段二 from tb m, (select min(序号) 序号 , 字段一 from tb group by 字段一 having count(1) > 1) n where m.字段一 = n.字段一)
)
order by 客户号drop table tb/*
客户号 序号 字段一 字段二 序号2
---------- ---------- ---------- ---------- ----------
A 10001 ss dd 10001
B 10002 aa cc 10002
C 10003 ss aa 10001
D 10004 bb cc 10002
E 10005 zz aa 10005(所影响的行数为 5 行)
*/
客户号 序号 字段一 字段二 序号2
---------- ---------- ---------- ---------- ----------
A 10001 ss dd 10001
B 10002 aa cc 10002
C 10003 ss aa 10001
D 10004 bb cc 10002
E 10005 zz aa 10005
F 10006 ss aa 10001 --按楼主的意思,序号2每个最多重复两次.(6 行受影响)
create table #test1 (客户号 varchar(10), 序号 int,字段一 varchar(10),字段二 varchar(10)) insert #test1 select 'A','10001','ss','dd'
insert #test1 select 'B','10002','aa','cc'
insert #test1 select 'C','10003','ss','aa'
insert #test1 select 'D','10004','bb','cc'
insert #test1 select 'E','10005','zz','aa'alter table #test1 add col1 int
alter table #test1 add rn int;with ct as (select *,rowid=row_number() over(order by 序号) from #test1 )
update ct
set rn=rowidcreate clustered index rn_idx on #test1(rn)--begin tran declare @temp table(客户号 varchar(10), 序号 int,字段一 varchar(10),字段二 varchar(10))
--declare @i int
--set @i=1
while 1=1
begin
;with ct as (select top 1 * from #test1 where col1 is null order by 序号)
update ct
set col1=序号
output inserted.客户号,inserted.序号,inserted.字段一,inserted.字段二 into @temp if @@rowcount<>0
begin
;with cte as( select top 1 a.*,b.序号 as col2
from #test1 a,@temp b
where a.序号>b.序号
and col1 is null
and (a.字段一=b.字段一
or a.字段二=b.字段二
or a.字段一=b.字段二
or a.字段二=b.字段一) order by a.序号)
update cte
set col1=col2
end
else
begin
break
end
endselect * from #test1
--
--rollback
/*客户号 序号 字段一 字段二 col1 rn
---------- ----------- ---------- ---------- ----------- -----------
A 10001 ss dd 10001 1
B 10002 aa cc 10002 2
C 10003 ss aa 10001 3
D 10004 bb cc 10002 4
E 10005 zz aa 10005 5(5 行受影响)*/
while 1=1
begin
;with ct as (select top 1 * from #test1 where col1 is null order by 序号)
update ct
set col1=序号
output inserted.客户号,inserted.序号,inserted.字段一,inserted.字段二 into @temp if @@rowcount<>0
begin
;with cte as( select top 1 a.*,b.序号 as col2
from #test1 a,@temp b
where a.序号>b.序号
and col1 is null
and (a.字段一=b.字段一
or a.字段二=b.字段二
or a.字段一=b.字段二
or a.字段二=b.字段一) order by a.序号)
update cte
set col1=col2
end
else
begin
break
end
delete from @temp --漏掉了
end
create table #tb(客户号 varchar(10), 序号 varchar(10),字段一 varchar(10), 字段二 varchar(10))
insert into #tb values('A','10001','ss','dd')
insert into #tb values('B','10002','aa','cc')
insert into #tb values('C','10003','ss','aa')
insert into #tb values('D','10004','bb','cc')
insert into #tb values('E','10005','zz','aa')
go
create table #tb1(客户号 varchar(10), 序号 varchar(10),字段一 varchar(10), 字段二 varchar(10),新客户号 varchar(10))declare fetch_temp cursor for select *,ROW_NUMBER() over(order by 客户号)from #tb
open fetch_temp
declare @cid varchar(10),
@sequence varchar(10),
@col1 varchar(10),
@col2 varchar(10),
@rid int,
@new_cid varchar(10)
fetch next from fetch_temp
into @cid,@sequence,@col1,@col2,@ridwhile @@fetch_status =0
begin
if @rid=1
begin
set @new_cid=@sequence
insert into #tb1 values(@cid,@sequence,@col1,@col2,@sequence)
end
else
begin
select @new_cid=(case
when exists(select * from #tb1 a where a.字段一=@col1 or (a.字段一!=@col1 and a.字段二=@col2)) then (select top 1 序号 from #tb1 a where a.字段一=@col1 or (a.字段一!=@col1 and a.字段二=@col2))
else @sequence
end)
insert into #tb1 values(@cid,@sequence,@col1,@col2,@new_cid)
end
fetch next from fetch_temp into @cid,@sequence,@col1,@col2,@rid
end
select * from #tb1
close fetch_temp
DEALLOCATE fetch_temp
INSERT @T(CustID,Seq,Field1,Field2)
SELECT 'A','10001','ss','dd'
UNION ALL SELECT 'B','10002','aa','cc'
UNION ALL SELECT 'C','10003','ss','aa'
UNION ALL SELECT 'D','10004','bb','cc'
UNION ALL SELECT 'E','10005','zz','aa' DECLARE @GroupID VARCHAR(20), @CurCustID VARCHAR(20)
WHILE EXISTS(SELECT 1 FROM @T WHERE GroupID IS NULL)
BEGIN
--找到下一个需要进行分组的记录
SELECT TOP 1 @GroupID=Seq, @CurCustID=CustID FROM @T WHERE GroupID IS NULL ORDER BY Seq ASC
--将所有相似记录分到同一个组
UPDATE @T SET GroupID=@GroupID WHERE CustID=@CurCustID
UPDATE b
SET b.GroupID=@GroupID
FROM @T AS a
INNER JOIN @T AS b ON b.Field1 LIKE a.Field1 OR b.Field2 LIKE a.Field2
WHERE a.CustID=@CurCustID AND b.CustID!=@CurCustID AND b.GroupID IS NULL
END SELECT * FROM @T