左连接错误

时间:2014-04-03 18:03:38

标签: sql oracle

我在VBA中访问ORACLE DB时有以下语句。我的问题是,当我运行查询时,我在左连接上收到错误:

  

错误ORA-00904无效标识符0100650.EEM_ID

我很困惑,因为我创建了类似的其他查询没有问题。任何帮助将不胜感激。谢谢!

SQLStr = "SELECT * FROM (SELECT LENGTH(( NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' ') )), NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' '), LENGTH(( NVL(O100668.EMAIL_ADDRESS,' ') )), NVL(O100668.EMAIL_ADDRESS,' '), O100650.FIRST_NAME, O100659.ID, O100650.LAST_NAME, O100650.PERSON_CODE, O100650.PRIME_ASSIGNMENT, ( P2K.P2K_SMGCD(O100650.DES_ID,'DES') ), ( P2K.P2K_SMGCD(O100564.BPN_ID,'BPN') ), " & _
" row_number() over (partition by O100650.PERSON_CODE order by O100650.PERSON_CODE ASC, O100650.PRIME_ASSIGNMENT ASC) rn " & _
"FROM P2K.P2K_BE_ENROLLMENTS O100564, P2K.P2K_BE_ENROLLMENT_DETAILS O100567, P2K.P2K_HR_VSASSIGNMENTS O100650, P2K.P2K_HR_EMPLOYMENTS O100659, P2K.P2K_HR_PERSONALS O100668 " & _
"LEFT OUTER JOIN P2K.P2K_BE_ENROLLMENTS O100564 on (O100564.EEM_ID = O100659.ID and O100564.BPN_ID=148) " & _
"WHERE ( ( O100650.EEM_ID = O100659.ID ) AND ( O100564.ID = O100567.BEN_ID ) AND ( O100650.EEM_ID = O100564.EEM_ID ) AND ( O100650.EID_ID = O100668.EID_ID ) ) AND ( ( P2K.P2K_SMGCD(O100650.DES_ID,'DES') ) IN ('ACTIVE','PENDING') ) AND ( ( LENGTH(( NVL(O100668.EMAIL_ADDRESS,' ') )) ) >= 3 ) AND ( (  ( ( LENGTH(( NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' ') )) ) <= 3 OR ( NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' ') ) IS NULL  )  ) ) AND ( TRUNC(SYSDATE) BETWEEN O100650.EFFECTIVE AND O100650.EXPIRY ) AND ( SYSDATE BETWEEN O100567.EFFECTIVE AND O100567.EXPIRY ) AND ( SYSDATE BETWEEN O100668.EFFECTIVE AND O100668.EXPIRY ) ) " & _
"WHERE rn=1 " & _
"ORDER BY O100650.LAST_NAME ASC ;"

3 个答案:

答案 0 :(得分:1)

我冒昧地将你的笛卡儿产品重写为可读的东西,以及一些难以辨认的东西。应避免使用旧的连接样式,只需指定每个连接条件,并为每个JOIN条件而不是where子句添加所有需要的逻辑。这实际上可以提高性能,因为服务器能够以更好的方式利用索引。

SELECT *
    FROM (
           SELECT LENGTH(( NVL(O100668.EMAIL_ADDRESS, ' ') ))
               ,LENGTH(( NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS', 'PENWAIVER', O100659.ID), ' ') ))
               ,NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS', 'PENWAIVER', O100659.ID), ' ')
               ,NVL(P2K.P2K_SMGETUDF('P2K_HR_PERSONALS', 'HOME EMAIL', O100668.ID), ' ')
               ,NVL(O100668.EMAIL_ADDRESS, ' ')
               ,O100650.FIRST_NAME
               ,O100659.ID
               ,O100650.LAST_NAME
               ,O100650.PERSON_CODE
               ,( P2K.P2K_SMGCD(O100650.DES_ID, 'DES') )
               ,( P2K.P2K_SMGCD(O100564.BPN_ID, 'BPN') )
               ,ROW_NUMBER() OVER ( PARTITION BY O100650.PERSON_CODE ORDER BY O100650.PERSON_CODE ASC ) rn
            FROM P2K.P2K_HR_VSASSIGNMENTS O100650
            JOIN P2K.P2K_BE_ENROLLMENTS O100564
                ON O100650.EEM_ID = O100564.EEM_ID
            JOIN P2K.P2K_HR_PERSONALS O100668
                ON O100650.EID_ID = O100668.EID_ID
                   AND ( SYSDATE BETWEEN O100668.EFFECTIVE AND O100668.EXPIRY )
                   AND ( ( LENGTH(( NVL(O100668.EMAIL_ADDRESS, ' ') )) ) >= 3 )
            JOIN P2K.P2K_HR_EMPLOYMENTS O100659
                ON O100650.EEM_ID = O100659.ID
                   AND ( (  ( ( LENGTH(( NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS', 'PENWAIVER', O100659.ID), ' ') )) ) <= 3
                         OR ( NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS', 'PENWAIVER', O100659.ID), ' ') ) IS NULL  )  )
                       )
            JOIN P2K.P2K_BE_ENROLLMENT_DETAILS O100567
                ON O100564.ID = O100567.BEN_ID
                   AND ( SYSDATE BETWEEN O100567.EFFECTIVE AND O100567.EXPIRY )
            LEFT OUTER JOIN P2K.P2K_BE_ENROLLMENTS O100564
                ON O100659.ID = O100564.EEM_ID
                   AND O100564.BPN_ID = 148
            WHERE ( TRUNC(SYSDATE) BETWEEN O100650.EFFECTIVE AND O100650.EXPIRY )
                AND ( ( P2K.P2K_SMGCD(O100650.DES_ID, 'DES') ) IN ( 'ACTIVE', 'PENDING' ) )
         )
    WHERE rn = 1
    ORDER BY O100650.LAST_NAME ASC;

答案 1 :(得分:0)

查看左连接线和最后一条线。那里有语法错误。

SELECT * 
FROM (
    SELECT LENGTH(( NVL(O100668.EMAIL_ADDRESS,' ') ))
        , LENGTH(( NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' ') ))
        , NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' ')
        , NVL(P2K.P2K_SMGETUDF('P2K_HR_PERSONALS','HOME EMAIL',O100668.ID),' ')
        , NVL(O100668.EMAIL_ADDRESS,' ')
        , O100650.FIRST_NAME
        , O100659.ID
        , O100650.LAST_NAME
        , O100650.PERSON_CODE
        , ( P2K.P2K_SMGCD(O100650.DES_ID,'DES') )
        , ( P2K.P2K_SMGCD(O100564.BPN_ID,'BPN') )
        ,   row_number() over (partition by O100650.PERSON_CODE order by O100650.PERSON_CODE ASC) rn 
        FROM P2K.P2K_BE_ENROLLMENTS O100564
            , P2K.P2K_BE_ENROLLMENT_DETAILS O100567
            , P2K.P2K_HR_VSASSIGNMENTS O100650
            , P2K.P2K_HR_EMPLOYMENTS O100659
            , P2K.P2K_HR_PERSONALS O100668 
        LEFT OUTER JOIN P2K.P2K_BE_ENROLLMENTS O100564 
            on (0100564.EEM_ID = O100659.ID and 0100564.BPN_ID=148) &   <--- this doesn't make sense
    WHERE ( ( O100650.EEM_ID = O100659.ID ) 
        AND ( O100564.ID = O100567.BEN_ID ) 
        AND ( O100650.EEM_ID = O100564.EEM_ID ) 
        AND ( O100650.EID_ID = O100668.EID_ID ) ) 
        AND ( ( P2K.P2K_SMGCD(O100650.DES_ID,'DES') ) IN ('ACTIVE','PENDING') ) 
        AND ( ( LENGTH(( NVL(O100668.EMAIL_ADDRESS,' ') )) ) >= 3 ) 
        AND ( (  ( ( LENGTH(( NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' ') )) ) <= 3 OR ( NVL(P2K.P2K_SMGETUDF('P2K_HR_EMPLOYMENTS','PENWAIVER',O100659.ID),' ') ) IS NULL  )  ) ) 
        AND ( TRUNC(SYSDATE) BETWEEN O100650.EFFECTIVE AND O100650.EXPIRY ) 
        AND ( SYSDATE BETWEEN O100567.EFFECTIVE AND O100567.EXPIRY ) 
        AND ( SYSDATE BETWEEN O100668.EFFECTIVE AND O100668.EXPIRY )) 

WHERE rn=1ORDER BY O100650.LAST_NAME ASC ;  <---there is no sapce after the 1

答案 2 :(得分:0)

我看到您加入0100564.EEM_ID = O100659.ID,但您的where子句中有O100650.EEM_ID = O100564.EEM_ID。这让我觉得你想要ID为0100659而不是EEM_ID。