SQL如何在多个可能性的连接上进行1to1匹配

时间:2017-05-10 14:01:20

标签: sql oracle

我不太确定如何正确地说出这一点。我有2个表在多列上匹配,但在其他列中具有不同的值。我需要让查询只选择一个匹配对。我已经包含了一些示例sql来测试。

   CREATE TABLE TEST1 
   (    
    LVL1 NUMBER, 
    LVL2 NUMBER, 
    LVL3 NUMBER, 
    DESCR VARCHAR2(30 BYTE)
   );

   CREATE TABLE TEST2 
   (    
    LVL1 NUMBER, 
    LVL2 NUMBER, 
    LVL3 NUMBER, 
    CID NUMBER
   );

   insert into test1 (lvl1, lvl2, lvl3, descr) values (101, 1, 1, 'lackadaisical'); 
   insert into test1 (lvl1, lvl2, lvl3, descr) values (101, 1, 1, 'martially'); 
   insert into test1 (lvl1, lvl2, lvl3, descr) values (101, 1, 2, 'brian'); 
   insert into test1 (lvl1, lvl2, lvl3, descr) values (101, 2, 1, 'symploce'); 
   insert into test1 (lvl1, lvl2, lvl3, descr) values (101, 2, 2, 'prismatoid'); 
   insert into test1 (lvl1, lvl2, lvl3, descr) values (101, 2, 3, 'delirious'); 
   insert into test1 (lvl1, lvl2, lvl3, descr) values (102, 1, 1, 'discontinuous'); 
   insert into test1 (lvl1, lvl2, lvl3, descr) values (102, 2, 1, 'subseptate'); 
   insert into test1 (lvl1, lvl2, lvl3, descr) values (102, 2, 1, 'heterodox'); 
   insert into test1 (lvl1, lvl2, lvl3, descr) values (102, 2, 1, 'liege'); 
   insert into test1 (lvl1, lvl2, lvl3, descr) values (103, 1, 1, 'mobbish'); 


   insert into test2 (lvl1, lvl2, lvl3, cid) values (101, 1, 1, 10); 
   insert into test2 (lvl1, lvl2, lvl3, cid) values (101, 1, 1, 15); 
   insert into test2 (lvl1, lvl2, lvl3, cid) values (101, 1, 2, 20); 
   insert into test2 (lvl1, lvl2, lvl3, cid) values (101, 2, 1, 25); 
   insert into test2 (lvl1, lvl2, lvl3, cid) values (101, 2, 2, 30); 
   insert into test2 (lvl1, lvl2, lvl3, cid) values (101, 2, 3, 35); 
   insert into test2 (lvl1, lvl2, lvl3, cid) values (102, 1, 1, 40); 
   insert into test2 (lvl1, lvl2, lvl3, cid) values (102, 2, 1, 45); 
   insert into test2 (lvl1, lvl2, lvl3, cid) values (102, 2, 1, 50); 
   insert into test2 (lvl1, lvl2, lvl3, cid) values (102, 2, 1, 55); 
   insert into test2 (lvl1, lvl2, lvl3, cid) values (103, 1, 1, 60); 

因此,每个表包含11个与lvl1,lvl2和lvl3匹配的行。我需要查询返回11行。将哪个descr与哪个cid匹配并不重要,尽管根据其他列放置优先级会很好。

运行以下查询返回19行,每个lvl1,lvl2,lvl3匹配的descr和cid组合的可能性。

   select 
     t1.lvl1,
     t1.lvl2,
     t1.lvl3,
     t1.descr,
     t2.cid
   from
     test1 t1,
     test2 t2
   where
     t2.lvl1 = t1.lvl1 and
     t2.lvl2 = t1.lvl2 and
     t2.lvl3 = t1.lvl3;




   LVL1       LVL2       LVL3       DESCR                                 CID
   ---------- ---------- ---------- ------------------------------ ----------
    101          1          1       martially                              10
    101          1          1       lackadaisical                          10
    101          1          1       martially                              15
    101          1          1       lackadaisical                          15
    101          1          2       brian                                  20
    101          2          1       symploce                               25
    101          2          2       prismatoid                             30
    101          2          3       delirious                              35
    102          1          1       discontinuous                          40
    102          2          1       liege                                  45
    102          2          1       heterodox                              45
    102          2          1       subseptate                             45
    102          2          1       liege                                  50
    102          2          1       heterodox                              50
    102          2          1       subseptate                             50
    102          2          1       liege                                  55
    102          2          1       heterodox                              55
    102          2          1       subseptate                             55
    103          1          1       mobbish                                60

   19 rows selected 

修改 对于每个匹配,我在descr或cid列中都没有任何重复项。例如,lvls 101-1-1有2个cid匹配(10,15)到2个descr(lackadaisical,martially)我需要2行101-1-1,其中每个descr配对; (lackadaisical,10和martially,15)或(lackadaisical,15和martially,10)。

1 个答案:

答案 0 :(得分:0)

使用row_number对行进行编号,并为每个组合只获取其中一行。

select * from (
select 
 t1.lvl1,
 t1.lvl2,
 t1.lvl3,
 t1.descr,
 t2.cid,
 row_number() over(partition by t1.lvl1,t1.lvl2,t1.lvl3,t1.descr order by t2.cid) as rnum
from
 test1 t1 
join test2 t2 on t2.lvl1 = t1.lvl1 and t2.lvl2 = t1.lvl2 and t2.lvl3 = t1.lvl3
) t 
 where rnum = 1

如果需要,可以通过修改order by中的row_number来确定优先级。