2016-05-04 29 views
1

表1 - DBT_C_INT_ACCRJOIN表查询给人怪异的结果

select INT_ACC.BRCH_CODE, INT_ACC.PROD_CODE, INT_ACC.REF_ID from DBT_C_INT_ACCR INT_ACC where BRCH_CODE = 784 and PROD_CODE = 'GF' and REF_ID = 'GFE1200077'; 

BRCH_CODE PROD_CODE REF_ID 
784    GF  GFE1200077 
784    GF  GFE1200077 
784    GF  GFE1200077 
784    GF  GFE1200077 

表2 - dbt_c_rate_refresh

select INT_ACC.BRCH_CODE, INT_ACC.PROD_CODE, INT_ACC.REF_ID from dbt_c_rate_refresh INT_ACC where BRCH_CODE = 784 and PROD_CODE = 'GF' and REF_ID = 'GFE1200077'; 


BRCH_CODE PROD_CODE REF_ID 
784   GF   GFE1200077 
784   GF   GFE1200077 
784   GF   GFE1200077 
784   GF   GFE1200077 
784   GF   GFE1200077 
784   GF   GFE1200077 
784   GF   GFE1200077 

现在,当下面尝试加入,它给了28行,而不是4排。任何解释吗?

select INT_ACC.ref_id, RATE_REFRESH.ref_id from DBT_C_INT_ACCR INT_ACC left OUTER JOIN dbt_c_rate_refresh RATE_REFRESH ON (INT_ACC.BRCH_CODE = RATE_REFRESH.BRCH_CODE and INT_ACC.PROD_CODE = RATE_REFRESH.PROD_CODE and INT_ACC.REF_ID = RATE_REFRESH.REF_ID) 
where INT_ACC.BRCH_CODE = '784' and INT_ACC.PROD_CODE = 'GF' and INT_ACC.REF_ID = 'GFE1200077'; 

REF_ID  REF_ID_1 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
GFE1200077 GFE1200077 
+0

它给出了相同的号码。任何类型的加入结果.. –

+0

您正在使用哪个RDMS ... mysql或oracle?当您加入多对多关系时,它会在连接中提供多行。 – mituw16

+0

Oracle one ...... –

回答

2

因为你不是唯一的东西加入,您实际上做一个笛卡尔其中有重复的两个表中连接条件值的行之间的连接(也称为交叉连接)。

为了证明,我模仿你的表,并增加了一个唯一的标识符rn,这样你可以看到当你做了什么情况的加入:

with dbt_c_int_accr as (select 784 brch_code, 'GF' prod_code, 'GFE1200077' ref_id, 1 rn from dual union all 
         select 784 brch_code, 'GF' prod_code, 'GFE1200077' ref_id, 2 rn from dual union all 
         select 784 brch_code, 'GF' prod_code, 'GFE1200077' ref_id, 3 rn from dual union all 
         select 784 brch_code, 'GF' prod_code, 'GFE1200077' ref_id, 4 rn from dual), 
dbt_c_rate_refresh as (select 784 brch_code, 'GF' prod_code, 'GFE1200077' ref_id, 1 rn from dual union all 
         select 784 brch_code, 'GF' prod_code, 'GFE1200077' ref_id, 2 rn from dual union all 
         select 784 brch_code, 'GF' prod_code, 'GFE1200077' ref_id, 3 rn from dual union all 
         select 784 brch_code, 'GF' prod_code, 'GFE1200077' ref_id, 4 rn from dual union all 
         select 784 brch_code, 'GF' prod_code, 'GFE1200077' ref_id, 5 rn from dual union all 
         select 784 brch_code, 'GF' prod_code, 'GFE1200077' ref_id, 6 rn from dual union all 
         select 784 brch_code, 'GF' prod_code, 'GFE1200077' ref_id, 7 rn from dual) 
-- end of mimicking your tables with data in. You wouldn't need the above subqueries, as you have the tables themselves. 
-- See the SQL below: 
select int_acc.ref_id, 
     rate_refresh.ref_id, 
     int_acc.rn, 
     rate_refresh.rn 
from dbt_c_int_accr int_acc 
     left outer join dbt_c_rate_refresh rate_refresh on (int_acc.brch_code = rate_refresh.brch_code 
                  and int_acc.prod_code = rate_refresh.prod_code 
                  and int_acc.ref_id = rate_refresh.ref_id) 
where int_acc.brch_code = '784' 
and int_acc.prod_code = 'GF' 
and int_acc.ref_id = 'GFE1200077' 
order by int_acc.rn, 
     rate_refresh.rn; 


REF_ID  REF_ID_1   RN  RN_1 
---------- ---------- ---------- ---------- 
GFE1200077 GFE1200077   1   1 
GFE1200077 GFE1200077   1   2 
GFE1200077 GFE1200077   1   3 
GFE1200077 GFE1200077   1   4 
GFE1200077 GFE1200077   1   5 
GFE1200077 GFE1200077   1   6 
GFE1200077 GFE1200077   1   7 
GFE1200077 GFE1200077   2   1 
GFE1200077 GFE1200077   2   2 
GFE1200077 GFE1200077   2   3 
GFE1200077 GFE1200077   2   4 
GFE1200077 GFE1200077   2   5 
GFE1200077 GFE1200077   2   6 
GFE1200077 GFE1200077   2   7 
GFE1200077 GFE1200077   3   1 
GFE1200077 GFE1200077   3   2 
GFE1200077 GFE1200077   3   3 
GFE1200077 GFE1200077   3   4 
GFE1200077 GFE1200077   3   5 
GFE1200077 GFE1200077   3   6 
GFE1200077 GFE1200077   3   7 
GFE1200077 GFE1200077   4   1 
GFE1200077 GFE1200077   4   2 
GFE1200077 GFE1200077   4   3 
GFE1200077 GFE1200077   4   4 
GFE1200077 GFE1200077   4   5 
GFE1200077 GFE1200077   4   6 
GFE1200077 GFE1200077   4   7 

希望你可以看到,rn = 1dbt_c_int_accr匹配的行到dbt_c_rate_refresh中的每一行。

这是因为brch_codeprod_coderef_idrn = 1dbt_c_int_accr比赛在同一列中的其他表的所有7行 - 根据您的连接条件。这同样适用于dbt_c_int_accr中的其他3行。

你得到28行,因为4 * 7 = 28

这不是一个奇怪的结果;它正好是你对这个特定的连接条件所要求的。如果你是在不同的结果之后,那么你必须相应地修改你的连接。

+0

谢谢......你还可以建议如何在上面的情况下获得4预期的行? –

+0

@SnehalMasne这取决于。获得4个输出行的逻辑是什么?也许你根本不需要加入? – Boneist

+0

左外部连接的一般逻辑 - 获取左边表的所有行和右边的常见行。在上面的例子中,如果没有重复,就会发生同样的情况。由于有重复,我得到了笛卡儿的结果 - 我如何克服这一点? –