【问题标题】:JOIN table query giving weird resultsJOIN 表查询给出奇怪的结果
【发布时间】:2016-08-29 22:37:12
【问题描述】:

表 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

【问题讨论】:

  • 它给出了相同的编号。任何类型的连接的结果..
  • 您使用的是哪个 RDMS... mysql 或 oracle?当您加入多对多关系时,它会在您的联接中提供多行。
  • 您的表中有 7 + 4 个完全相等的行,因此连接只执行笛卡尔 (7*4)。你为什么期望 4 个?

标签: sql oracle select join


【解决方案1】:

因为您没有加入独特的事物,所以您实际上是在两个表中具有重复连接条件值的行之间进行笛卡尔连接(也称为交叉连接)。

为了演示,我模仿了您的表格并添加了一个唯一标识符 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

希望您能看到dbt_c_int_accr 中带有rn = 1 的行与dbt_c_rate_refresh 中的每一行相匹配。

这是因为 dbt_c_int_accrrn = 1brch_codeprod_coderef_id 列与其他表中所有 7 行的相同列匹配 - 根据您的连接条件。 dbt_c_int_accr 中的其他 3 行也是如此。

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

这不是一个奇怪的结果; 正是您在该特定连接条件下所要求的。如果您追求不同的结果,那么您必须相应地修改您的加入。

【讨论】:

  • 谢谢...您能否就上述情况下如何获得 4 行预期的行提供建议?
  • @SnehalMasne 这取决于。获得 4 个输出行的逻辑是什么?也许您根本不需要加入?
  • 左外连接的一般逻辑——获取左表的所有行和右表的公共行。如果没有重复,上面的例子也会发生同样的情况。由于有重复,我得到笛卡尔结果 - 我该如何克服?
  • 你为什么要首先尝试外部加入?你真正想要解决的问题是什么?这是一个家庭作业问题,还是你真的有包含这些数据的生产表?加入行的目的是什么?加入表格后,您希望在表格中显示其他列吗?
  • 上面显示的只是一组必需的列。存在 100 个其他列并且具有差异值。有这样的业务案例需要处理上述连接表然后处理其他列的场景。无论如何,非常感谢您的澄清:)
猜你喜欢
  • 2018-09-01
  • 2019-03-29
  • 2013-08-20
  • 2019-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多