INNER加入ORACLE

时间:2014-11-13 15:00:33

标签: oracle inner-join

我的INNER join for Oracle存在问题。我希望你们能够复习。基本上,地址表包含事件和人员的地址。我基本上需要为事件地址执行SELECT语句,然后INNER联接以获取人员地址,由于某种原因它不起作用。

 select DISTINCT  INCIDENT_PEOPLE_VW.INC_REPORT_NUMBER,trunc((to_number(to_char            (offense_status_date,'yyyymmdd'))-to_number(to_char(DOB,'yyyymmdd')))/10000)  as AGE,
 INCIDENT_PEOPLE_VW.INCIDENT_ID,
 OFFENSES.OFFENSE_STATUS_DATE,
 INCIDENT_PEOPLE_VW.AGNCY_CD_AGENCY_CODE,
 INCIDENT_PEOPLE_VW.STATUS,
 INCIDENT_PEOPLE_VW.SEX_SEX_CODE,
  INCIDENT_PEOPLE_VW.RACE_RACE_CODE,
 INCIDENT_PEOPLE_VW.LNAME,
 INCIDENT_PEOPLE_VW.FNAME,
   INCIDENT_PEOPLE_VW.DOB,
 OFFENSES.REMARKS,
 OFFENSE_CODES.OFFENSE_DESC,
 P.LONGITUDE,P.LATITUDE,
 suspicion_Codes.DESCRIPTION,
 P.STREET_NUMBER, P.STREET_NAME,P.STREET_CD_STREET_TYPE_CODE,P.CITY,P.STATE_CD_STATE_CODE,P.ZIP5,
 AH.STREET_NUMBER,    AH.STREET_NAME,AH.STREET_CD_STREET_TYPE_CODE,AH.CITY,AH.STATE_CD_STATE_CODE,AH.ZIP5
 from
 INCIDENT_PEOPLE_VW,
 OFFICER_INCIDENTS,OFFENSES,OFFENSE_CODES, OFFICERS,
 ADDRESSES P, INCIDENT_ADDRESSES,offender_suspicions,suspicion_Codes,person_addresses D
 INNER JOIN ADDRESSES ah
 ON D.address_id= ah.address_ID
 where OFFICER_INCIDENTS.INC_INCIDENT_ID=INCIDENT_PEOPLE_VW.INCIDENT_ID
 AND INCIDENT_PEOPLE_VW.INCIDENT_ID=INCIDENT_ADDRESSES.INCIDENT_ID
 AND INCIDENT_ADDRESSES.ADDRESS_ID=P.ADDRESS_ID
 AND INCIDENT_PEOPLE_VW.INCIDENT_ID = OFFENSES.INC_INCIDENT_ID
 AND INCIDENT_PEOPLE_VW.INCIDENT_ID = OFFENDER_SUSPICIONS.OFFNSE_INC_INCIDENT_ID
 AND OFFENDER_SUSPICIONS.SUSPICN_CD_SUSPICION_CODE =SUSPICION_CODES.SUSPICION_CODE
 AND OFFENSES.OFFNS_CD_OFFENSE_CODE = OFFENSE_CODES.OFFENSE_CODE
 AND OFFICER_INCIDENTS.OFF1_OFFICER_ID = OFFICERS.OFFICER_ID
 and OFFICER_INCIDENTS.ORC_ROLE_CODE='R'
 and incident_people_vw.status='A'
 and INCIDENT_PEOPLE_VW.ROLE_ROLE_TYPE IN ('A','S')
 AND trunc((to_number(to_char(offense_status_date,'yyyymmdd'))-to_number(to_char    (DOB,'yyyymmdd')))/10000)  <= 17

1 个答案:

答案 0 :(得分:0)

你的查询失败的确切原因是@ Politank-Z写给你的那个......

您正在将ANSI的连接语法与&#34; old&#34;混合使用。在WHERE子句中使用连接谓词的语法。

如果你一直使用ANSI语法,你很容易发现问题,因为你的person_addresses表连接缺少实际的连接谓词,因此,你的数据库服务器正在做一个笛卡尔积,而是有效地吞噬所有临时表空间。

在这里,您对查询进行了轻微的反复修改......

迭代1 - 引入基本缩进并将所有WHERE子句连接谓词重新编译为ANSI连接

select distinct
    INCIDENT_PEOPLE_VW.INC_REPORT_NUMBER,
    trunc((to_number(to_char(offense_status_date,'yyyymmdd')) - to_number(to_char(DOB,'yyyymmdd')))/10000)  as AGE,
    INCIDENT_PEOPLE_VW.INCIDENT_ID,
    OFFENSES.OFFENSE_STATUS_DATE,
    INCIDENT_PEOPLE_VW.AGNCY_CD_AGENCY_CODE,
    INCIDENT_PEOPLE_VW.STATUS,
    INCIDENT_PEOPLE_VW.SEX_SEX_CODE,
    INCIDENT_PEOPLE_VW.RACE_RACE_CODE,
    INCIDENT_PEOPLE_VW.LNAME,
    INCIDENT_PEOPLE_VW.FNAME,
    INCIDENT_PEOPLE_VW.DOB,
    OFFENSES.REMARKS,
    OFFENSE_CODES.OFFENSE_DESC,
    P.LONGITUDE,P.LATITUDE,
    suspicion_Codes.DESCRIPTION,
    P.STREET_NUMBER, P.STREET_NAME,P.STREET_CD_STREET_TYPE_CODE,P.CITY,P.STATE_CD_STATE_CODE,P.ZIP5,
    AH.STREET_NUMBER, AH.STREET_NAME,AH.STREET_CD_STREET_TYPE_CODE,AH.CITY,AH.STATE_CD_STATE_CODE,AH.ZIP5
from
    INCIDENT_PEOPLE_VW
    join OFFICER_INCIDENTS
        on OFFICER_INCIDENTS.INC_INCIDENT_ID = INCIDENT_PEOPLE_VW.INCIDENT_ID
    join OFFENSES
        on OFFENSES.INC_INCIDENT_ID = INCIDENT_PEOPLE_VW.INCIDENT_ID
    join OFFENSE_CODES
        on OFFENSE_CODES.OFFENSE_CODE = OFFENSES.OFFNS_CD_OFFENSE_CODE
    join OFFICERS
        on OFFICERS.OFFICER_ID = OFFICER_INCIDENTS.OFF1_OFFICER_ID
    join INCIDENT_ADDRESSES
        on INCIDENT_ADDRESSES.INCIDENT_ID = INCIDENT_PEOPLE_VW.INCIDENT_ID
    join ADDRESSES P
        on P.ADDRESS_ID = INCIDENT_ADDRESSES.ADDRESS_ID
    join offender_suspicions
        on OFFENDER_SUSPICIONS.OFFNSE_INC_INCIDENT_ID = INCIDENT_PEOPLE_VW.INCIDENT_ID
    join suspicion_Codes
        on SUSPICION_CODES.SUSPICION_CODE = OFFENDER_SUSPICIONS.SUSPICN_CD_SUSPICION_CODE
    person_addresses D,
    INNER JOIN ADDRESSES ah
        ON ah.address_ID = D.address_id
where
    OFFICER_INCIDENTS.ORC_ROLE_CODE = 'R' and
    incident_people_vw.status = 'A' and
    INCIDENT_PEOPLE_VW.ROLE_ROLE_TYPE IN ('A','S') and
    trunc((to_number(to_char(offense_status_date,'yyyymmdd'))-to_number(to_char(DOB,'yyyymmdd')))/10000)  <= 17
;

迭代2 - 识别错误遗忘的笛卡儿产品(即没有连接谓词的连接,因为当您将所有连接谓词放入WHERE子句时, EASILY 会忘记一些)

在这种情况下,它是PERSON_ADDRESSES表。

迭代3 - 修复丢失的连接谓词

select distinct
    INCIDENT_PEOPLE_VW.INC_REPORT_NUMBER,
    trunc((to_number(to_char(offense_status_date,'yyyymmdd')) - to_number(to_char(DOB,'yyyymmdd')))/10000)  as AGE,
    INCIDENT_PEOPLE_VW.INCIDENT_ID,
    OFFENSES.OFFENSE_STATUS_DATE,
    INCIDENT_PEOPLE_VW.AGNCY_CD_AGENCY_CODE,
    INCIDENT_PEOPLE_VW.STATUS,
    INCIDENT_PEOPLE_VW.SEX_SEX_CODE,
    INCIDENT_PEOPLE_VW.RACE_RACE_CODE,
    INCIDENT_PEOPLE_VW.LNAME,
    INCIDENT_PEOPLE_VW.FNAME,
    INCIDENT_PEOPLE_VW.DOB,
    OFFENSES.REMARKS,
    OFFENSE_CODES.OFFENSE_DESC,
    P.LONGITUDE,P.LATITUDE,
    suspicion_Codes.DESCRIPTION,
    P.STREET_NUMBER, P.STREET_NAME,P.STREET_CD_STREET_TYPE_CODE,P.CITY,P.STATE_CD_STATE_CODE,P.ZIP5,
    AH.STREET_NUMBER, AH.STREET_NAME,AH.STREET_CD_STREET_TYPE_CODE,AH.CITY,AH.STATE_CD_STATE_CODE,AH.ZIP5
from
    INCIDENT_PEOPLE_VW
    join OFFICER_INCIDENTS
        on OFFICER_INCIDENTS.INC_INCIDENT_ID = INCIDENT_PEOPLE_VW.INCIDENT_ID
    join OFFENSES
        on OFFENSES.INC_INCIDENT_ID = INCIDENT_PEOPLE_VW.INCIDENT_ID
    join OFFENSE_CODES
        on OFFENSE_CODES.OFFENSE_CODE = OFFENSES.OFFNS_CD_OFFENSE_CODE
    join OFFICERS
        on OFFICERS.OFFICER_ID = OFFICER_INCIDENTS.OFF1_OFFICER_ID
    join INCIDENT_ADDRESSES
        on INCIDENT_ADDRESSES.INCIDENT_ID = INCIDENT_PEOPLE_VW.INCIDENT_ID
    join ADDRESSES P
        on P.ADDRESS_ID = INCIDENT_ADDRESSES.ADDRESS_ID
    join offender_suspicions
        on OFFENDER_SUSPICIONS.OFFNSE_INC_INCIDENT_ID = INCIDENT_PEOPLE_VW.INCIDENT_ID
    join suspicion_Codes
        on SUSPICION_CODES.SUSPICION_CODE = OFFENDER_SUSPICIONS.SUSPICN_CD_SUSPICION_CODE
    join person_addresses D
        on D.<some column> = <some table from the above ones>.<some column from the table>
    JOIN ADDRESSES ah
        ON AH.address_id = D.address_id
where
    OFFICER_INCIDENTS.ORC_ROLE_CODE = 'R' and
    incident_people_vw.status = 'A' and
    INCIDENT_PEOPLE_VW.ROLE_ROLE_TYPE IN ('A','S') and
    trunc((to_number(to_char(offense_status_date,'yyyymmdd'))-to_number(to_char(DOB,'yyyymmdd')))/10000)  <= 17
;

迭代4 - 修复奇怪的年龄计算,引入一致的格式和一致的表别名以提高可读性

select distinct
    IP.incident_id, IP.inc_report_number,
--    trunc((to_number(to_char(OFS.offense_status_date,'yyyymmdd')) - to_number(to_char(IP.dob,'yyyymmdd')))/10000)  as age,
    months_between(OFS.offense_status_date, IP.dob) / 12 as age
    OFS.offense_status_date,
    IP.agncy_cd_agency_code, IP.status, IP.sex_sex_code, IP.race_race_code, IP.lname, IP.fname, IP.dob,
    OFS.remarks,
    OC.offense_desc,
    AIA.longitude, AIA.latitude,
    SC.description,
    AIA.street_number, AIA.street_name, AIA.street_cd_street_type_code, AIA.city, AIA.state_cd_state_code, AIA.zip5,
    PAA.street_number, PAA.street_name, PAA.street_cd_street_type_code, PAA.city, PAA.state_cd_state_code, PAA.zip5
from
    incident_people_vw IP
    join officer_incidents OI
        on OI.inc_incident_id = IP.incident_id
    join offenses OFS
        on OFS.inc_incident_id = IP.incident_id
    join offense_codes OC
        on OC.offense_code = OFS.offns_cd_offense_code
    join officers O
        on O.officer_id = OI.off1_officer_id
    join incident_addresses IA
        on IA.incident_id = IP.incident_id
    join addresses AIA
        on AIA.address_id = IA.address_id
    join offender_suspicions OS
        on OS.offnse_inc_incident_id = IP.incident_id
    join suspicion_codes SC
        on SC.suspicion_code = OS.suspicn_cd_suspicion_code
    join person_addresses PA
        on PA.<some column> = <some table alias from the above ones>.<some column from the table>
    join addresses PAA
        on PAA.address_id = PA.address_id
where
    OI.orc_role_code = 'R' and
    IP.status = 'A' and
    IP.role_role_type in ('A','S') and
--    trunc((to_number(to_char(OFS.offense_status_date,'yyyymmdd')) - to_number(to_char(IP.dob,'yyyymmdd')))/10000)  <= 17
    months_between(OFS.offense_status_date, IP.dob) / 12 <= 17
;

享受。从现在起始终使用ANSI连接语法。