假设我有三个表,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具有匹配的索引,而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
我知道这不起作用,因为A中的每一行都会匹配B中的所有行,然后匹配C中的所有行。换句话说,没有唯一的匹配。
我认为另一种方法是使用两种选择:
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)
表A
和B
具有一对一的关系。因此,根据每个ID的顺序将它们加入到一个唯一的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中完成,但这取决于您的实现
答案 1 :(得分: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"