将Oracle SQL转换为Access Jet SQL,Left Join

时间:2011-10-03 21:47:05

标签: sql oracle ms-access left-join jet

我必须在这里找到一些东西。我在Toad中有这个漂亮的,漂亮的Oracle SQL语句,它给我一个包含我想要的ID的所有活动人员的列表:

SELECT PERSONNEL.PERSON_ID,
       PERSONNEL.NAME_LAST_KEY,
       PERSONNEL.NAME_FIRST_KEY,
       PA_EID.ALIAS EID,
       PA_IDTWO.ALIAS IDTWO,
       PA_LIC.ALIAS LICENSENO
  FROM PERSONNEL
       LEFT JOIN PERSONNEL_ALIAS PA_EID
          ON     PERSONNEL.PERSON_ID = PA_EID.PERSON_ID
             AND PA_EID.PERSONNEL_ALIAS_TYPE_CD = 1086
             AND PA_EID.ALIAS_POOL_CD = 3796547
             AND PERSONNEL.ACTIVE_IND = 1
       LEFT JOIN PERSONNEL_ALIAS PA_IDTWO
          ON     PERSONNEL.PERSON_ID = PA_IDTWO.PERSON_ID
             AND PA_IDTWO.PERSONNEL_ALIAS_TYPE_CD = 3839085
             AND PA_IDTWO.ACTIVE_IND = 1
       LEFT JOIN PERSONNEL_ALIAS PA_LIC
          ON     PERSONNEL.PERSON_ID = PA_LIC.PERSON_ID
             AND PA_LIC.PERSONNEL_ALIAS_TYPE_CD = 1087
             AND PA_LIC.ALIAS_POOL_CD = 683988
             AND PA_LIC.ACTIVE_IND = 1
 WHERE PERSONNEL.ACTIVE_IND = 1 AND PERSONNEL.PHYSICIAN_IND = 1;

这很好用。我遇到问题的地方是我把它放入Access。我知道,我知道,Access Sucks。有时需要使用它,特别是如果一个人有多个数据库类型,他们只想存储几个查询,而尤其是,如果一个人的老板只知道Access。无论如何,我在FROM中遇到了AND,所以我把它们移到了WHERE,但由于一些奇怪的原因,Access没有进行LEFT JOIN,只返回 那些有EID的人员, IDTWO和LICENSENO的。不是每个人都拥有这三个。

到目前为止,Access中的最佳镜头是:

SELECT PERSONNEL.PERSON_ID, 
            PERSONNEL.NAME_LAST_KEY, 
            PERSONNEL.NAME_FIRST_KEY, 
            PA_EID.ALIAS AS EID, 
            PA_IDTWO.ALIAS AS ID2, 
            PA_LIC.ALIAS AS LICENSENO

FROM ((PERSONNEL 
        LEFT JOIN PERSONNEL_ALIAS AS PA_EID ON PERSONNEL.PERSON_ID=PA_EID.PERSON_ID) 
        LEFT JOIN PERSONNEL_ALIAS AS PA_IDTWO ON PERSONNEL.PERSON_ID=PA_IDTWO.PERSON_ID) 
        LEFT JOIN PERSONNEL_ALIAS AS PA_LIC ON PERSONNEL.PERSON_ID=PA_LIC.PERSON_ID

WHERE (((PERSONNEL.ACTIVE_IND)=1) 
        AND ((PERSONNEL.PHYSICIAN_IND)=1) 
        AND ((PA_EID.PRSNL_ALIAS_TYPE_CD)=1086) 
        AND ((PA_EID.ALIAS_POOL_CD)=3796547) 
        AND ((PA_IDTWO.PRSNL_ALIAS_TYPE_CD)=3839085) 
        AND ((PA_IDTWO.ACTIVE_IND)=1) 
        AND ((PA_LIC.PRSNL_ALIAS_TYPE_CD)=1087) 
        AND ((PA_LIC.ALIAS_POOL_CD)=683988) 
        AND ((PA_LIC.ACTIVE_IND)=1));

我认为问题的一部分可能是我正在为所有三个连接使用相同的别名(查找)表。也许这是一种更有效的方法吗? SQL版还是新手,所以任何提示都会很棒。我觉得这些应该是等价的,但是Toad查询给了我许多成千上万个不完美的行,而Access给了我少于500个。我需要找到每个人以便没有人被遗漏。这几乎就像LEFT JOIN在Access中 >一样。

2 个答案:

答案 0 :(得分:1)

要了解您在做什么,让我们看看您的查询的简化版本:

SELECT PERSONNEL.PERSON_ID,    
       PA_EID.ALIAS AS EID          
FROM PERSONNEL         
LEFT JOIN PERSONNEL_ALIAS AS PA_EID ON PERSONNEL.PERSON_ID=PA_EID.PERSON_ID         
WHERE PERSONNEL.ACTIVE_IND=1       
        AND PERSONNEL.PHYSICIAN_IND=1      
        AND PA_EID.PRSNL_ALIAS_TYPE_CD=1086
        AND PA_EID.ALIAS_POOL_CD=3796547     

如果LEFT JOIN找到匹配项,您的行可能如下所示:

Person_ID    EID
12345        JDB

如果找不到匹配项(忽略WHERE子句一秒钟),它可能看起来像:

Person_ID    EID
12345        NULL

当您添加上面的WHERE子句时,您告诉它只在PERSONNEL_ALIAS表中查找满足条件的记录,但是如果没有找到记录,那么这些值将被视为NULL,因此它们永远不会满足WHERE条件没有记录会回来......

正如Joe Stefanelli在他的评论中所说,在LEFT JOIN'ed表中添加一个WHERE子句使其成为一个INNER JOIN而不是......

答案 1 :(得分:1)

除了@ Sparky的答案之外,为了获得与您在Oracle中所做的相同的操作,您需要在加入它们之前从连接的“外部”表中的表中过滤行。一种方法可能是:

  1. 对于需要从中过滤行的连接的“外部”侧的每个表(即PERSONNEL_ALIAS的三个实例),创建一个过滤所需行的查询。例如,第一个查询(例如名为PA_EID)可能如下所示:SELECT PERSONNEL_ALIAS.* FROM PERSONNEL_ALIAS WHERE PERSONNEL_ALIAS.PERSONNEL_ALIAS_TYPE_CD = 1086 AND PERSONNEL_ALIAS.ALIAS_POOL_CD = 3796547

  2. 在原始帖子中的“目前为止访问中的最佳镜头”查询中:a)将PERSONNEL_ALIAS的每个实例替换为步骤1中创建的相应查询,并且,b)删除相应的条件(在PA_EID上,来自WHERE子句的PA_IDTWO和PA_LIC)。