2014-03-19 55 views
0

假设我有三个表,A,B和C:避免多行中加入

表A:

C1 C2 Dt 
------------- 
1 2 8 pm 
1 2 10 pm 

表B:

C1 C2 Ind 
------------- 
1 2 123 
1 2 456 

表C:

C1 C2 C3 C4 Ind 
------------------- 
1 2 a b 123 
1 2 c d 123 
1 2 e f 123 
1 2 g h 456 

正如你所看到的,表B和C有一个matchi ng索引,而A不。我怎样才能连接这三个表,这样A的第一行(按'dt'列排序)将只匹配C中的行,哪个索引是B中的第一行(由Ind排序)?这同样适用于其他行。

我曾尝试是创建一个简单的连接:

SELECT * 
FROM A JOIN B 
     ON A.C1 = B.C1 
     AND A.C2 = B.C2 
JOIN C ON A.C1 = C.C1 
     AND A.C2 = C.C2 
     AND B.IND = C.IND 

我知道这是不行的,因为在每一行会匹配在B中的所有行,然后匹配C中的所有行换句话说,没有唯一的匹配。

另一种方法我想到2所选择的利用:

SELECT * 
FROM B JOIN (
      SELECT C1, C2, C3, C4, Ind, 
        row_number() OVER (PARTITION BY C1, C2, ind ORDER BY C1, C2, ind) AS num_row 
      FROM C 
      ) table_c 
     ON B.IND = table_c.IND 
     AND B.C1 = table_c.C1 
     AND B.C2 = table_c.C2 
JOIN (
     SELECT C1, C2, DT, row_number() OVER (ORDER BY DT) AS num_row 
     FROM A 
     ) table_a 
     ON table_a.num_row = table_c.num_row 
     AND table_a.C1 = table_c.C1 
     AND table_a.C2 = table_c.C2 

但这些表是非常大,每次我都试过的办法,会使用多种选择,是非常缓慢的。所以我想知道什么是最好的方法来做到这一点。

+0

请编辑您的问题并添加所需的结果。 –

+0

你有什么试过自己,结果又不符合你的期望?即不要求我们为您编写所有代码......; –

+0

刚刚编辑,谢谢你们。 –

回答

0

AB有一对一的关系。因此,根据每个订单的顺序将它们加入到一个唯一的ID中即可解决问题的第一部分。

create table newA as select rownum as uniq_id, A.* from A order by dt; 
create table newB as select rownum as uniq_id, B.* from B order by ind; 
select * from newA inner join newB on newA.uniq_id = newB.uniq_id; 

然后用您的新查询加入C

select * 
from 
    C 
inner join (select 
      newB.Ind as ind 
      from 
       newA 
       inner join newB on newA.uniq_id = newB.uniq_id) 
      as sub on C.ind = sub.ind 

我敢肯定,这可以用临时表来完成或严格SQL但这将取决于您的实现

0

您可以使用ROW_NUMBER有效这里

WITH arn 
    AS (SELECT a.c1, 
       a.c2, 
       "Dt", 
       Row_number() 
        over ( 
        PARTITION BY a.c1, a.c2 
        ORDER BY "Dt")rn 
     FROM a), 
    brn 
    AS (SELECT b.c1, 
       b.c2, 
       b."Ind", 
       Row_number() 
        over ( 
        PARTITION BY b.c1, b.c2 
        ORDER BY b."Ind") rn 
     FROM b) 
SELECT * 
FROM arn a 
     inner join brn b 
       ON a.c1 = b.c1 
        AND a.c2 = b.c2 
        AND a.rn = b.rn 
     Inner join c 
       ON b.c1 = c.c1 
        AND b.c2 = c.c2 
        AND b."Ind" = c."Ind" 

Demo