SQL在两个表的匹配行上选择一行

时间:2017-04-03 14:13:03

标签: sql

我有两个具有相同字段的表,但最终值的计算方式略有不同。我需要将这两个表中的数据合并为一个,但是当匹配时需要优先考虑一个记录而不是另一个记录。你知道这怎么可能吗?

下面是两个匹配记录的模拟:

ID  Balance     Type    CCY  Payment        Final_Balance
28  1068376.037 F - CC  GBP  78124          990252.0367
28  1068376.037 F - DD  GBP  982905         85470.08293

如果格式不佳,我很抱歉,我不确定如何格式化表数据。

我在这两个表中有数千条记录,但是对于少数记录,我在两个表中都有相同的信息。基本上我想要的是有匹配的地方,我希望它通过F-DD选择F-CC,所以我最终在最后一张表中找到了独特的记录。

由于

2 个答案:

答案 0 :(得分:0)

我个人使用ROW_NUMBER()来做这样的事情,但可能有更好的解决方案。

您可以重新运行此SQL以显示如何慢慢构建最终答案:

declare @t1 table (id int)
declare @t2 table (id int, txt varchar(2))

insert into @t1 
select 1 union
select 2

insert into @t2
select 1, 'FC' union
select 1, 'FD' union
select 2, 'FC' union
select 2, 'FD'

select *, row_number() over (partition by id order by txt) as we_want_the_ones 
from @t2

select * from (
    select id, txt, row_number() over (partition by id order by txt) as we_want_the_ones 
    from @t2
) z
where we_want_the_ones = 1

select * 
from @t1 a
join (
    select * from (
        select id, txt, row_number() over (partition by id order by txt) as we_want_the_ones 
        from @t2
    ) z
    where we_want_the_ones = 1
) b on a.id = b.id

答案 1 :(得分:0)

我对这个问题的理解是你有两个表(AB),它们具有完全相同的列。您希望将UNION这些表分成一个数据集,但有时您在两个表中有行" 匹配"彼此。在这种情况下,您只能根据某些优先级获取其中一行。

从你的例子看来......

  • 匹配ID相同时发生。
  • 优先级:基于Type列,按字母顺序排列较低的顺序排列。

我也是假设SQL Server,因为那是我喜欢的,你没有说。

希望所有这一切都是正确的......现在,我就是这样做的。

我首先要执行两个表的UNION。记录所有记录并且不用担心匹配,将它们放在临时表中以便以后使用。

SELECT ID, Balance, Type, CCY, Payment, Final_Balance
INTO #AllRecords
FROM A
UNION
SELECT ID, Balance, Type, CCY, Payment, Final_Balance
FROM B

接下来,我会GROUP BY确定匹配项的字段,然后使用MINMAX来获取优先级列的正确值。通过我对你的问题的理解,这意味着..

SELECT ID, MIN(Type) AS Type
FROM #AllRecords
GROUP BY ID

使用该查询,您现在拥有要在最终结果中显示的所有记录的自然键。剩下要做的就是使用这些键查找其余列,我们可以通过将该查询用作子查询来完成此操作。

SELECT ID, Balance, Type, CCY, Payment, Final_Balance
FROM #AllRecords r
INNER JOIN (
    SELECT ID, MIN(Type) AS Type
    FROM #AllRecords
    GROUP BY ID ) final ON r.ID = final.ID AND r.Type = final.Type

所以一起生成的查询就是..

SELECT ID, Balance, Type, CCY, Payment, Final_Balance
INTO #AllRecords
FROM A
UNION
SELECT ID, Balance, Type, CCY, Payment, Final_Balance
FROM B

SELECT ID, Balance, Type, CCY, Payment, Final_Balance
FROM #AllRecords r
INNER JOIN (
    SELECT ID, MIN(Type) AS Type
    FROM #AllRecords
    GROUP BY ID ) final ON r.ID = final.ID AND r.Type = final.Type