Перевод Oracle SQL в Access Jet SQL, левое соединение - PullRequest
0 голосов
/ 04 октября 2011

Там должно быть что-то, что я здесь упускаю. У меня есть замечательный оператор Oracle SQL в Toad, который возвращает мне список всех активных сотрудников с нужными мне идентификаторами:

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 сосет. Иногда нужно использовать его, особенно если у вас есть несколько типов баз данных, в которых они просто хотят хранить несколько запросов, и , особенно , если босс знает только Access. В любом случае, у меня были проблемы с AND внутри FROM, поэтому я переместил их в WHERE, но по какой-то странной причине Access не выполняет LEFT JOINs, возвращая только персонал с EID, IDTWO и ЛИЦЕНЗЕНЫ. Не у всех есть все три из них.

Лучший выстрел в 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. Мне нужно найти всех , чтобы никто не остался в стороне. Это почти как если бы ЛЕВЫЕ СОЕДИНЕНИЯ вообще не работают в Access.

Ответы [ 2 ]

1 голос
/ 04 октября 2011

В дополнение к ответу @ 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. В вашем запросе «лучший выстрел в Access до сих пор» в исходной публикации: a) замените каждый экземпляр PERSONNEL_ALIAS на соответствующий запрос, созданный на шаге 1, и, b) удалите соответствующие условия (для PA_EID, PA_IDTWO и PA_LIC) из предложения WHERE.

1 голос
/ 04 октября 2011

Чтобы понять, что вы делаете, давайте посмотрим на упрощенную версию вашего запроса:

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, которые удовлетворяют условию, но если записи не найдены, то значения считаются пустыми, поэтому они никогда не будут удовлетворять условию WHERE и никакие записи не вернутся ...

Как сказал Джо Стефанелли в своем комментарии, добавление предложения WHERE к таблице LEFT JOIN заставляет ее действовать как ВНУТРЕННЕЕ СОЕДИНЕНИЕ ...

...