2014-03-19 93 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