Oracle Query ORA-01799:列可能不是外部连接到子查询

时间:2016-08-10 14:41:43

标签: sql oracle

我写了一个有效数周的查询,但今天早上我的Select Inner Join

出现了以下错误
  

ORA-01799:列可能不是外部连接到子查询

这是我的查询

SELECT 
     PERSON.PERSONID, 
     PERSON.LASTNAME, 
     PERSON.FIRSTNAME, 
     PERSON.MIDDLENAME,


FROM PERSON_VIEW PERSON
LEFT JOIN (SELECT PERSONID, DRIVERLICENSE_NUM, DRIVERLICENSE_EXP_DT,UPDATED_DT  
                        FROM DRIVERLICENSE_VIEW) DRIVERLICENSE
ON DRIVERLICENSE.PERSONID = PERSON.PERSONID AND 
       ((trunc(sysdate) - DRIVERLICENSE.UPDATED_DT <= 1000)) AND
       DRIVERLICENSE_EXP_DT = (SELECT MAX(DRIVERLICENSE_EXP_DT)   
                               FROM DRIVERLICENSE_VIEW PPT
                               WHERE PPT.PERSONID = DRIVERLICENSE_VIEW.PERSONID)

当我删除内部查询时,它可以工作,但这已经工作了几个星期。

DRIVERLICENSE_EXP_DT = (SELECT MAX(DRIVERLICENSE_EXP_DT)   
                        FROM DRIVERLICENSE_VIEW PPT
                        WHERE PPT.PERSONID = DRIVERLICENSE_VIEW.PERSONID)

如何修复此查询以便再次使用?

感谢。

2 个答案:

答案 0 :(得分:1)

您可以使用分析row_number()功能来识别具有最新到期日期的记录。因此,将以下表达式添加到内部选择列表中:

ROW_NUMBER() OVER (PARTITION BY PERSONID ORDER BY DRIVERLICENSE_EXP_DT DESC) AS RN

...然后将结果过滤到RN = 1而不是子查询检查:

SELECT    PERSON.PERSONID, 
          PERSON.LASTNAME, 
          PERSON.FIRSTNAME, 
          PERSON.MIDDLENAME,
          DRIVERLICENSE.DRIVERLICENSE_NUM, 
          DRIVERLICENSE.DRIVERLICENSE_EXP_DT,
          DRIVERLICENSE.UPDATED_DT
FROM      PERSON_VIEW PERSON
LEFT JOIN (SELECT PERSONID, 
                  DRIVERLICENSE_NUM, 
                  DRIVERLICENSE_EXP_DT,
                  UPDATED_DT,
                  ROW_NUMBER() OVER (PARTITION BY PERSONID 
                                     ORDER BY DRIVERLICENSE_EXP_DT DESC) AS RN
           FROM   DRIVERLICENSE_VIEW) DRIVERLICENSE
        ON DRIVERLICENSE.PERSONID = PERSON.PERSONID
       AND trunc(sysdate) - DRIVERLICENSE.UPDATED_DT <= 1000
       AND RN = 1

如果您要在子查询中移动sysdate测试,我还希望您可以获得一些可能感兴趣的非空驱动程序许可证结果 - 但这一切都取决于您希望实现的目标:

SELECT    PERSON.PERSONID, 
          PERSON.LASTNAME, 
          PERSON.FIRSTNAME, 
          PERSON.MIDDLENAME,
          DRIVERLICENSE.DRIVERLICENSE_NUM, 
          DRIVERLICENSE.DRIVERLICENSE_EXP_DT,
          DRIVERLICENSE.UPDATED_DT
FROM      PERSON_VIEW PERSON
LEFT JOIN (SELECT PERSONID, 
                  DRIVERLICENSE_NUM, 
                  DRIVERLICENSE_EXP_DT,
                  UPDATED_DT,
                  ROW_NUMBER() OVER (PARTITION BY PERSONID 
                                     ORDER BY DRIVERLICENSE_EXP_DT DESC) AS RN
           FROM   DRIVERLICENSE_VIEW
           WHERE  trunc(sysdate) - UPDATED_DT <= 1000) DRIVERLICENSE
        ON DRIVERLICENSE.PERSONID = PERSON.PERSONID
       AND RN = 1

最后,我想你也在主driverlicense的{​​{1}}中选择了一些字段,否则在执行select时几乎没用。

答案 1 :(得分:1)

SELECT   
 PERSON.PERSONID,   
 PERSON.LASTNAME,  
 PERSON.FIRSTNAME,  
 PERSON.MIDDLENAME  
FROM PERSON_VIEW PERSON  
LEFT JOIN (SELECT PERSONID,  
    DRIVERLICENSE_NUM,  
    DRIVERLICENSE_EXP_DT,  
    UPDATED_DT    
    FROM DRIVERLICENSE_VIEW) DRIVERLICENSE  
ON DRIVERLICENSE.PERSONID = PERSON.PERSONID  
    AND ((trunc(SYSDATE) - DRIVERLICENSE.UPDATED_DT <= 1000))  
    AND DRIVERLICENSE_EXP_DT = (SELECT MAX(DRIVERLICENSE_EXP_DT)   
                            FROM   DRIVERLICENSE_VIEW PPT  
                            WHERE PPT.PERSONID = DRIVERLICENSE.PERSONID)

您在最后一行中有错误,因为您在查询中没有任何对象DRIVERLICENSE_VIEW,您的别名为DRIVERLICENSE。我希望这会奏效。

您可以在左连接中直接使用表而不是子查询,因为它的工作方式相同:

SELECT 
 PERSON.PERSONID, 
 PERSON.LASTNAME, 
 PERSON.FIRSTNAME, 
 PERSON.MIDDLENAME
FROM PERSON_VIEW PERSON
LEFT JOIN DRIVERLICENSE_VIEW DRIVERLICENSE ON DRIVERLICENSE.PERSONID = PERSON.PERSONID 
AND ((trunc(SYSDATE) - DRIVERLICENSE.UPDATED_DT <= 1000))
AND DRIVERLICENSE_EXP_DT = (SELECT MAX(DRIVERLICENSE_EXP_DT)   
       FROM DRIVERLICENSE_VIEW PPT WHERE PPT.PERSONID = DRIVERLICENSE.PERSONID)