将Oracle SQL转换为访问Jet SQL,左连接

将Oracle SQL转换为访问Jet SQL,左连接,sql,oracle,ms-access,left-join,jet,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 PE

这里一定有什么我遗漏了。我在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时。我知道,我知道,接触很糟糕。有时需要使用它,特别是当一个人有多个数据库类型,他们只想在其中存储一些查询时,尤其是当一个人的老板只知道访问权限时。无论如何,我在FROM中遇到了and问题,所以我将它们移到了WHERE,但出于某种奇怪的原因,Access没有进行左连接,只返回那些具有EID、IDTWO和LICENSENO的人员。不是每个人都有这三个

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

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));

我认为问题的一部分可能是我对所有三个连接使用了相同的别名(查找)表。也许有更有效的方法?对于SQLLand来说还是个新手,所以任何关于这方面的提示都是非常棒的。我觉得这些应该是等价的,但是Toad查询返回了成千上万个不完美的行,Access返回的不到500行。我需要找到所有人,这样就不会遗漏任何人。在Access中,左连接几乎完全不起作用。。

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

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     
如果左连接找到匹配项,则行可能如下所示:

Person_ID    EID
12345        JDB
如果没有找到匹配项(暂时忽略WHERE子句),它可能看起来像:

Person_ID    EID
12345        NULL
当您添加上面的WHERE子句时,您告诉它只在Personal_ALIAS表中查找满足条件的记录,但是如果找不到任何记录,则这些值将被视为NULL,因此它们永远不会满足WHERE条件,并且不会返回任何记录


正如Joe Stefanelli在其评论中所说,在左联接表中添加WHERE子句使其充当内部联接…

进一步说到@Sparky的答案,要获得与在Oracle中所做的相同的结果,您需要在联接之前过滤联接“外部”表中的行。一种方法可能是:

  • 对于联接“外部”侧的每个表,您需要从中筛选行(即Personal_ALIAS的三个实例),创建一个查询来筛选所需的行。例如,第一个查询(例如,名为PA_EID)可能如下所示:
    SELECT person_ALIAS.*FROM person_ALIAS,其中person_ALIAS.person_ALIAS_TYPE_CD=1086和person_ALIAS.ALIAS_POOL_CD=3796547

  • 在原始帖子中的“迄今为止访问的最佳快照”查询中:a)用步骤1中创建的相应查询替换Personal_ALIAS的每个实例,以及b)从WHERE子句中删除相应的条件(在PA_EID、PA_IDTWO和PA_LIC上)


  • 每当您在WHERE子句中测试左联接表的列值(不是IS NULL/IS NOT NULL)时,您都会强制该联接的行为就像它是一个内部联接一样。因此,如果我要将这些WHERE条件添加回FROM in访问中,那么我会得到我想要的结果吗?我还得再和括号里的词作斗争。谢谢啊。再多的括号也不能使这一点起作用。无论我做什么,Access中总是出现“连接表达式不受支持”错误:/好的,我最后做的是在“子查询的”WHERE语句中使用我想要的AND进行3次访问查询,然后左键将它们加入到我的主人员表中。感谢tons关于WHERE语句的教育;我需要记住,访问方式不同于SQL方式。这就是我最终要做的,但是使用Access的点击查询。过滤掉以前工作的,然后当它们被连接时,子查询中为空的将在主查询中以空结尾。谢谢如果我有15个代表,我会投票给你。我会投票给他,因为他在答案中添加了有益的信息。