SQL完全外部联接,无重复,条件类似

时间:2019-10-12 07:54:52

标签: sql sql-server

以下是两个表。

我想在具有值-1或+1的两个表之间查找并联接记录。 但是在那种情况下,它也会返回我重复的记录。 没有重复记录,如何获得结果?

enter image description here

drop table if exists #A

CREATE TABLE #A(ID float, Category varchar(10), Amount float )
insert into #A values

(1,'A',150.4),
(2,'A',151.0),
(3,'A',149.8),
(4,'A',165.0),
(5,'A',165.0)

drop table if exists #B

CREATE TABLE #B(BID float, BCategory varchar(10), BAmount float )
insert into #B values

(95,'A',151),
(101,'A',150),
(115,'A',165.0),
(118,'A',165.0)

我尝试了以下查询,该查询返回重复项。

select * 
from
    (select 
         ID, category, Amount, 
         row_number() over (partition by category, Amount order by category, Amount) as Sr 
     from #A) A
full outer join
    (select 
         BID, Bcategory, BAmount, 
         row_number() over (partition by Bcategory, BAmount order by Bcategory, BAmount) as Sr 
     from #B) B on a.category = b.bCategory 
                and a.amount between b.bamount - 1 and b.BAmount + 1 
                and a.sr = b.sr

逻辑:当前用户如何手动映射:-

首先,尝试与另一个表进行精确匹配(类别和金额)。 然后,剩下的都尝试将类别和金额与TableB的(+/- 1)匹配。

因此,A的149.8或150.4都可以与B的150连接。由于只剩下表B中的一个(150),并且在完全匹配的情况下151已经分配给151,因此A的一条记录将被连接为空。

比方说,由于150.4在tableA中首先出现,因此可以与150的TableB一起使用。

149.8将保持无与伦比。实际上,用户不介意与或匹配。重要的是,任何一行(150.4或149.8)都应匹配为null。左外部连接或完全外部连接的问题是,将B的150分配给了这两者(149.8和150.4)。

1 个答案:

答案 0 :(得分:1)

如果要唯一记录,我们需要在表之间映射关系

  

表定义

drop table if exists #A

CREATE TABLE #A(ID float, Category varchar(10), Amount float )
insert into #A values

(1,'A',150.4),
(2,'A',151.0),
(3,'A',149.8),
(4,'A',165.0),
(5,'A',165.0)

drop table if exists #B

CREATE TABLE #B(AID float,BID float, BCategory varchar(10), BAmount float )
insert into #B values

(2,95,'A',151),
(1,101,'A',150),
(4,115,'A',165.0),
(5,118,'A',165.0)
  

查询

SELECT * FROM #A A
LEFT JOIN #B B ON  A.ID = B.AID
  

其他方式

select * 
from
    (select 
         ID, category, Amount, 
         row_number() over (partition by category, Amount order by category, Amount) as Sr 
     from #A) A
full outer join
    (select 
         AID,BID, Bcategory, BAmount, 
         row_number() over (partition by Bcategory, BAmount order by Bcategory, BAmount) as Sr 
     from #B) B on a.category = b.bCategory 
                and a.amount between b.bamount - 1 and b.BAmount + 1 
                and a.sr = b.sr AND A.ID = B.AID
  

输出结果

Output