Цель моего запроса — связать записи DateTimeIn и DateTimeOut между двумя таблицами по RegistrationNumber. (Данные взяты из опроса об использовании парковок...)
Сначала я попробовал соединение, но оно не справилось со сложностью. Например, у транспортного средства может быть DateTimeOut (оно выехало с парковки), но не может быть DateTimeIn (оно никогда не парковалось, возможно, потому, что все отсеки были заняты). Кроме того, я должен убедиться, что первый DateTimeIn связан с самым ранним DateTimeOut и что каждый DateTime связан только один раз.
Следующий «вложенный запрос», похоже, выполнил свою работу, но вернул ложноположительные результаты. Я понятия не имею, как они были созданы. Даже если для RegistrationNumber не было DateTimeOut, он возвращался. Как ни странно, после того, как все ссылки на таблицы были сделаны явными, эти ложные срабатывания были устранены.
-- Implicit reference to the second table (causes false positives):
SELECT
RegistrationNumber,
DateTimeIn,
(SELECT MIN(O.DateTimeOut) FROM HobieBeachVehiclesOut O WHERE O.RegistrationNumber = RegistrationNumber AND O.DateTimeOut > DateTimeIn) AS DateTimeOut
FROM HobieBeachVehiclesIn
ORDER BY DateTimeIn, RegistrationNumber
-- Explicit references all round (no glaring errors):
SELECT
RegistrationNumber,
DateTimeIn,
(SELECT MIN(O.DateTimeOut) FROM HobieBeachVehiclesOut O WHERE O.RegistrationNumber = A.RegistrationNumber AND O.DateTimeOut > A.DateTimeIn) AS DateTimeOut
FROM HobieBeachVehiclesIn A
ORDER BY DateTimeIn, RegistrationNumber
Результаты:
-- Implicit reference to the second table (causes false positives):
JHB 036 03/05/2019 00:09:00 03/05/2019 06:08:00
FNB 559 03/05/2019 06:00:00 03/05/2019 06:08:00
HGB 115 03/05/2019 06:05:00 03/05/2019 06:08:00
-- Explicit references all round (no glaring errors):
JHB 036 03/05/2019 00:09:00 NULL
FNB 559 03/05/2019 06:00:00 03/05/2019 06:48:00
HGB 115 03/05/2019 06:05:00 03/05/2019 07:53:00
Ошибки понятны и теперь, при втором взгляде, еще более своеобразны. Откуда взялся этот DateTimeOut? И почему запрос не может обработать «неявную ссылку» на dbo.HobieBeachVehiclesIn?
в запросе, когда вы не указываете псевдоним для своего столбца, псевдоним предполагается. Предполагаемый псевдоним — это любая таблица, в которой есть столбец, который вы используете. Это отлично работает, и вы получите сообщение об ошибке только в том случае, если в вашем запросе есть более одной таблицы с одним и тем же столбцом... и в этот момент вам нужно использовать псевдоним.
Таким образом, в вашем первом запросе с регистрационным номером без псевдонима предполагается, что столбец RegistrationNumber исходит из единственной таблицы в запросе... с псевдонимом "O". Это то же самое, что написать «ГДЕ РегистрационныйНомер = РегистрационныйНомер» в вашем подзапросе.
Чтобы написать коррелированный подзапрос (это то, что у вас есть... подзапрос, который ссылается на столбец вне себя), вы ДОЛЖНЫ включить псевдоним внешнего запроса. SQL, как я уже сказал, будет использовать псевдоним, если псевдоним не указан, но он будет использовать только таблицу ВНУТРИ того же запроса. Он не будет искать предполагаемый псевдоним таблицы снаружи.
Оглядываясь назад, ответ кажется таким очевидным! Как я мог ожидать, что подзапрос будет ссылаться на таблицу, которая ему не была открыта?! Вероятно, типографика - не рассматривать этот запрос как отдельный запрос или что-то в этом роде... Но теперь я понимаю. Спасибо за откровение.