SQL Запрос не существует - PullRequest
0 голосов
/ 21 июня 2020

У меня есть 2 стола, Основная и Платежи. Main - это таблица транзакций, Payments - это таблица, в которой транзакции оплачивают другие транзакции.

Main имеет множество полей, таких как Invo, InvoDate и Amount.

Payments очень просто; в нем есть только PayInvo и DueInvo. [и ПК]

Я должен выяснить, какой из тех, что все еще ожидали оплаты, к концу 2019 года. Мой подход был следующим. [Main.Ac1 - это счет. Вся кредиторская задолженность находится между 2000 и 2999]

SELECT * FROM Main 
WHERE InvoDate BETWEEN #1/1/2019# AND #12/31/2019# 
AND Main.Ac1 BETWEEN 2000 AND 2999 
AND NOT EXISTS 
( 
SELECT * FROM 
Payments INNER JOIN Main ON Payments.PayInvo = Main.Invo 
WHERE Main.InvoDate BETWEEN #1/1/2019# AND #12/31/2019#
);

Я ожидал, что он вернет ТОЛЬКО список транзакций, в которых Main.Ac1 МЕЖДУ 2000 И 2999, а также где соответствующий платеж НЕ был датирован 2019 годом, но он ничего не возвращает.

Ответы [ 2 ]

3 голосов
/ 21 июня 2020

Ваша проблема в том, что подзапрос в вашем предложении NOT EXISTS не коррелирован с вашим основным запросом, поэтому он всегда возвращает результат (до тех пор, пока в Payments есть какие-либо строки), и поэтому NOT EXISTS возвращает false и вы не получите строк из вашего запроса. Вы можете сопоставить подзапрос, не JOIN ing с Main, а вместо этого ссылаясь на таблицу Main из внешнего запроса:

SELECT * 
FROM Main 
WHERE InvoDate BETWEEN #1/1/2019# AND #12/31/2019# 
  AND Main.Ac1 BETWEEN 2000 AND 2999 
  AND NOT EXISTS 
  ( 
    SELECT *
    FROM Payments
    WHERE Payments.PayInvo = Main.Invo 
  )

Обратите внимание, что вам не нужен тест даты в подзапросе поскольку это покрывается внешним запросом.

0 голосов
/ 21 июня 2020

Ник предоставил прекрасное объяснение проблемы с вашим существующим запросом. Просто чтобы предложить альтернативу, обратите внимание, что это также может быть выполнено с помощью внешнего соединения без подзапроса, например

select main.* 
from 
    main left join payments on main.invo = payments.payinvo
where
    main.invodate between #1/1/2019# and #12/31/2019# and 
    main.ac1 between 2000 and 2999 and 
    payments.payinvo is null
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...