JOIN表查询给出了奇怪的结果

时间:2016-05-04 13:00:31

标签: sql oracle select join

表1 - DBT_C_INT_ACCR

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

现在尝试使用下面的Join时,它会提供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

1 个答案:

答案 0 :(得分: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_code的{​​{1}},ref_idrn = 1列与所有7行的其他表中的相同列匹配 - 根据您的加入条件。这同样适用于dbt_c_int_accr中的其他3行。

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

这不是一个奇怪的结果;它是完全您要求的特定连接条件。如果您的结果不同,那么您必须相应地修改您的联接。