Как правильно использовать два оператора Not Exists в предложении where с помощью Access SQL VBA? - PullRequest
5 голосов
/ 02 апреля 2010

У меня есть 3 таблицы: не слышал, анализировал, анализировал2. В каждой из этих таблиц есть два столбца с именами UnitID и Address.

То, что я пытаюсь сделать прямо сейчас, - это выбрать все записи для столбцов UnitID и Address из NotHeard, которые не отображаются ни в проанализированном, ни в анализированном2. SQL-оператор, который я создал, был следующим:

SELECT UnitID, Address  
INTO [NotHeardByEither] 
FROM [NotHeard] 
Where NOT EXISTS( Select analyzed.UnitID FROM analyzed WHERE [NotHeard].UnitID = analyzed.UnitID) 
or NOT EXISTS( Select analyzed2.UnitID FROM analyzed2 WHERE [NotHeard].UnitID = analyzed2.UnitID) 
Group BY UnitID, Address 

Я думал, что это сработает, поскольку я использовал одну строку подзапроса NOT EXISTS, и в прошлом она работала для меня просто отлично. Приведенный выше запрос, однако, возвращает те же данные, что и в таблице NotHeard, тогда как, если я уберу часть или NOT EXISTS, она будет работать правильно.

Есть идеи о том, что я делаю неправильно или как делать то, что я хочу сделать?

Ответы [ 2 ]

7 голосов
/ 02 апреля 2010

Относительно вашего исходного запроса, попробуйте

NOT (
   EXISTS( 
    Select analyzed.UnitID FROM analyzed WHERE [NotHeard].UnitID = analyzed.UnitID) 
AND EXISTS( 
    Select analyzed2.UnitID FROM analyzed2 WHERE [NotHeard].UnitID = analyzed2.UnitID) 
    )

, что означало бы не в любом. Но это равняется тому, что было у вас изначально (проверено на данных образца). Вы уверены, что не имеете в виду ни в A, ни в B? Это было бы

NOT (
   EXISTS( 
    Select analyzed.UnitID FROM analyzed WHERE [NotHeard].UnitID = analyzed.UnitID) 
OR EXISTS( 
    Select analyzed2.UnitID FROM analyzed2 WHERE [NotHeard].UnitID = analyzed2.UnitID) 
    )

Понимаете, что решение EXISTS использует коррелированные подзапросы, которые могут работать хуже, чем LEFT JOIN и NULL, вот пример.

SELECT NotHeard.UnitID, NotHeard.Address
FROM (NotHeard LEFT JOIN analyzed ON NotHeard.UnitID = analyzed.UnitID) 
     LEFT JOIN analyzed2 ON NotHeard.UnitID = analyzed2.UnitID
WHERE analyzed.UnitID Is Null OR analyzed2.UnitID Is Null
GROUP BY NotHeard.UnitID, NotHeard.Address;

Обратите внимание, что я использовал ИЛИ в состоянии по сравнению с решением Остина, И не дал бы вам ни анализируемого, ни анализируемого 2.

0 голосов
/ 02 апреля 2010

Похоже, что вы хотите, чтобы левые соединения вместо этого. Я могу быть немного не в своем синтаксисе Access.

SELECT UnitID, Address  
INTO [NotHeardByEither] 
FROM [NotHeard] 
    LEFT JOIN [analyzed] ON [NotHeard].UnitID = [analyzed].UnitID
    LEFT JOIN [analyzed2] ON [NotHeard].UnitID = [analyzed2].UnitID
WHERE IsNull([analyzed].UnitID)
    AND IsNull([analyzed2].UnitID)
Group BY UnitID, Address 
...