Oracle join 返回太多行

时间:2021-02-26 19:11:32

标签: oracle inner-join

我在 Oracle 19 中有以下选择语句:

select count(*) as facility_load_stg_cnt from facility_load_stg;

select count(*) as facility_cnt from facility;

select count(*) as loctn_typ_cnt from loctn_typ;

select count(*) as join_cnt from (
select f.facility_id, lt.loctn_typ_id
from facility_load_stg stg
inner join facility f on stg.facility_cd = f.facility_cd
inner join loctn_typ lt on stg.bldg = lt.loctn_typ_nm);

对象很简单,获取设施和 loctn_typ (facility_id, loctn_typ_id) 的 PK 以插入到将建立关系的表中。

问题是当我运行上面的代码时,我得到了这些结果:


FACILITY_LOAD_STG_CNT
---------------------
                  987


FACILITY_CNT
------------
         645


LOCTN_TYP_CNT
-------------
          188


  JOIN_CNT
----------
      2905

为什么带有连接的选择有 3 倍于 factory_load_stg 表的行数?我确定我在做一些愚蠢的事情,我只是看不到它。

人们要求查看表格定义,这是相关部分:

create table FACILITY_MAINT_DATA.FACILITY_LOAD_STG
(
    FACILITY_CD VARCHAR2(100) not null,
    BLDG VARCHAR2(100)
)

create table FACILITY_MAINT_DATA.FACILITY
(
    FACILITY_CD VARCHAR2(100),
    FACILITY_ID NUMBER(14) not null
        constraint PK_FACILITY
            primary key
)

create table FACILITY_MAINT_DATA.LOCTN_TYP
(
    LOCTN_TYP_ID NUMBER(14) default "FACILITY_MAINT_DATA"."LOCTN_TYP_ID_SEQ"."NEXTVAL" not null
        constraint PK_LOCTN_TYP
            primary key,
    LOCTN_TYP_NM VARCHAR2(100),
)

2 个答案:

答案 0 :(得分:1)

如果您加入并且遇到您期望的更高计数,一般规则是加入键不是唯一的*

这里有一个简单的例子,再现了与您相同的结果(仅限于两个表)。

create table tab1 as
select rownum id, 
case when rownum <= 80 then 'CD_'||rownum else 'CD_X' end cd from dual connect by level <= 645;

create table tab2 as
select rownum id, 
case when rownum <= 80 then 'CD_'||rownum 
when rownum <= 85 then 'CD_X'
else 'CD_Y' end cd from dual connect by level <= 987;

select count(*) from tab1;

  COUNT(*)
----------
       645

select count(*) from tab2;

  COUNT(*)
----------
       987

select count(*) 
from tab1
join tab2
on tab1.cd = tab2.cd;

  COUNT(*)
----------
      2905

摘要更改联接以使用唯一键或将联接限制为仅此类CD列是唯一的。

答案 1 :(得分:0)

感谢大家的评论,这让我看到了实际数据的详细信息,并且存在重复。现在我只需要弄清楚原因,只需要进行一些调查:)