2016-07-28 48 views
1

我在尝试弄清楚如何编写将返回左表中找到的相同数量记录的sql语句时遇到了一些问题。加入后,将返回左表中找到的相同数量的记录

例如,我们有两个表,交易和合作伙伴。由于表格最初是如何设计的,因此不存在检索完全匹配对的方法。 IE浏览器。交易可能有许多与之相关的合作伙伴。

我想要做的是显示所有与合作伙伴ID的交易。如果一项交易有多个匹配的合作伙伴ID,那么我需要首先进行比赛并丢掉其余的比赛。如果交易没有匹配的合作伙伴ID,我仍然需要显示它,但合作伙伴ID的值为空或空值。

事务表

Transaction ID | ID 1 | ID 2 
-------------- +---------+---------- 
T1    | A  | 1 
T2    | C  | 3 
T3    | B  | 1 
T4    | D  | 4 
T5    | A  | 2 

合伙表

Transaction ID | ID 1 | ID 2 
---------------+---------+---------- 
P1    | A  | 1 
P2    | B  | 2 
P3    | C  | 3 
P4    | C  | 3 
P5    | D  | 4 

预期的效果

Transaction ID| ID 1 | ID 2  | Partner ID 
--------------+---------+----------+----------- 
T1   | A  | 1  | P1 
T2   | C  | 3  | P3 
T3   | B  | 1  | Null 
T4   | D  | 4  | P5 
T5   | A  | 2  | Null 

我觉得我需要某种形式的外连接,以确保没有交易不查询,但我不知道如何确保没有显示重复的交易。

感谢

回答

1

SQL表没有“第一个”记录的概念,没有一些列来指定排序。但是,你想要什么的基本思想采用left joinrow_number()

select t.*, p.partnerid 
from transaction t left join 
    (select p.*, 
      row_number() over (partition by id1, id2 order by partnerid) as seqnum 
     from partner p 
    ) p 
    on t.id1 = p.id1 and t.id2 = p.id2 and p.seqnum = 1; 

该版本以“第一”的意思是“伙伴ID的最低值”。

+0

非常感谢该工作完美。 – Soul3lade

0

您可以使用outer joinrow_number

select * 
from (
    select t1.transactionid, t1.id1, t1.id2, t2.transactionid as partnerid, 
      row_number() over (partition by t1.transactionid order by t2.transactionid) rn 
    from Transaction t1 
     left join Partner t2 on t1.id1 = t2.id1 and t1.id2 = t2.id2 
) t 
where rn = 1 

这将选择从transaction表中的所有记录,然后仅1从partner表,如果它的存在。

0

我不知道你怎么知道你不想P4T2合作以及P3,但我发现这个工作对我来说,假设它的lowest ID

select t1.transactionid, t1.id1, t1.id2, min(t2.transactionid) as partnerid 
from Transaction t1, Partner t2 where t1.id1 = t2.id1(+) and t1.id2 = t2.id2(+) 
group by t1.transactionid, t1.id1, t1.id2 
order by t1.transactionid, t1.id1, t1.id2 
+0

我为这个问题大大简化了表格,但基本上每个合作伙伴都会有一个合作伙伴名称。在表中,可能有3个合作伙伴设置了不同的交易,但他们每个都有相同的名称。我需要展示的是该合作伙伴的名称,因此,一个交易与多个合作伙伴匹配并不重要,因为我要追踪的这一列在这些合作伙伴之间是相同的。 – Soul3lade

相关问题