在SQL Server中仅使用每条记录查找一次匹配对

在SQL Server中仅使用每条记录查找一次匹配对,sql,sql-server,tsql,pairwise,Sql,Sql Server,Tsql,Pairwise,我需要在SQL Server中找到匹配的记录对,但每条记录只能包含在1对中。一旦一条记录与一对匹配,就应该将其从任何未来对的考虑中删除 我尝试过涉及行号()和铅()的解决方案,但我就是没能达到目的 这将用于根据多个客户属性(如信用评分、收入等)将金融账户与类似账户配对以供审查 声明: declare @test table (ID numeric, Color varchar(20)) insert into @test values (1,'Blue'),(2,'Red'),(

我需要在SQL Server中找到匹配的记录对,但每条记录只能包含在1对中。一旦一条记录与一对匹配,就应该将其从任何未来对的考虑中删除

我尝试过涉及
行号()
铅()
的解决方案,但我就是没能达到目的

这将用于根据多个客户属性(如信用评分、收入等)将金融账户与类似账户配对以供审查

声明:

declare @test table (ID numeric, Color varchar(20))
insert into @test values
        (1,'Blue'),(2,'Red'),(3,'Blue'),(4,'Yellow'),(5,'Blue'),(6,'Red')

select* 
from @test t1
join @test t2 
    on t1.Color = t2.Color
    and t1.ID < t2.ID           -----removes reverse-pairs and self-pairs
所需成果:

ID  Color   ID  Color
--- ------- --- --------
1   Blue    3   Blue
2   Red     6   Red

您可以使用
row\u number()
和条件聚合:

select
    max(case when rn % 2 = 0 then id end) id1,
    max(case when rn % 2 = 0 then color end) color1,
    max(case when rn % 2 = 1 then id end) id2,
    max(case when rn % 2 = 1 then color end) color2
from (
    select
        t.*,
        row_number() over(partition by color order by id) - 1 rn
    from @test t
) t
group by color, rn / 2
having count(*) = 2
子查询通过增加
id
对具有相同
颜色的记录进行排序。然后,外部查询组成对,并对确实包含两条记录的组进行筛选

id1 | color1 | id2 | color2 :-- | :----- | :-- | :----- 1 | Blue | 3 | Blue 2 | Red | 6 | Red id1 |颜色1 | id2 |颜色2 :-- | :----- | :-- | :----- 1 |蓝色| 3 |蓝色 2 |红色| 6 |红色
使用最大评论进行编辑

这里有一个方法来完成这件事

我首先根据颜色对记录进行排序,最低id为rnk=1,下一个为rnk=2

declare @test table (ID numeric, Color varchar(20))
insert into @test values
        (1,'Blue'),(2,'Red'),(3,'Blue'),(4,'Yellow'),(5,'Blue'),(6,'Red'),(7,'Blue')

;with data
  as (select row_number() over(partition by color order by id asc) as rnk
            ,color
            ,id
       from @test
       )
select a.id,a.color,b.id,b.color
 from data a
 join data b
   on a.Color=b.Color
  and b.rnk=a.rnk+1
where a.rnk%2=1
之后,我通过拉取rnk=1记录,然后用rnk=2连接,将表连接在一起

declare @test table (ID numeric, Color varchar(20))
insert into @test values
        (1,'Blue'),(2,'Red'),(3,'Blue'),(4,'Yellow'),(5,'Blue'),(6,'Red'),(7,'Blue')

;with data
  as (select row_number() over(partition by color order by id asc) as rnk
            ,color
            ,id
       from @test
       )
select a.id,a.color,b.id,b.color
 from data a
 join data b
   on a.Color=b.Color
  and b.rnk=a.rnk+1
where a.rnk%2=1
我得到如下输出

+----+-------+----+-------+
| id | color | id | color |
+----+-------+----+-------+
|  1 | Blue  |  3 | Blue  |
|  5 | Blue  |  7 | Blue  |
|  2 | Red   |  6 | Red   |
+----+-------+----+-------+

我怎样才能增强这个很棒的解决方案,以捕获与前两张唱片颜色相同的其他唱片对?例如,如果第7个ID也是蓝色的,那么该ID可以与ID 5配对。我可以使用AND((a.rnk=1和b.rnk=2)或(a.rnk=3和b.rnk=4))来实现这一点,但是有没有更好的方法来捕获更多的对?@CarlyReum
其中a.RowNum%2=1和b.RowNum=a.RowNum+1
(并从连接中删除
和b.rnk=2
子句)。完美的这结合了@GMB所做的,但没有聚合,以及GeorgeJoseph所做的!谢谢大家!!