Почему (и как) «неявные» ссылки на таблицу FROM приводят к возврату ложных результатов в этом запросе?

Цель моего запроса — связать записи 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?

3 метода стилизации элементов HTML
3 метода стилизации элементов HTML
Когда дело доходит до применения какого-либо стиля к нашему HTML, существует три подхода: встроенный, внутренний и внешний. Предпочтительным обычно...
Формы c голосовым вводом в React с помощью Speechly
Формы c голосовым вводом в React с помощью Speechly
Пытались ли вы когда-нибудь заполнить веб-форму в области электронной коммерции, которая требует много кликов и выбора? Вас попросят заполнить дату,...
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Стилизация и валидация html-формы без использования JavaScript (только HTML/CSS)
Будучи разработчиком веб-приложений, легко впасть в заблуждение, считая, что приложение без JavaScript не имеет права на жизнь. Нам становится удобно...
Flatpickr: простой модуль календаря для вашего приложения на React
Flatpickr: простой модуль календаря для вашего приложения на React
Если вы ищете пакет для быстрой интеграции календаря с выбором даты в ваше приложения, то библиотека Flatpickr отлично справится с этой задачей....
В чем разница между Promise и Observable?
В чем разница между Promise и Observable?
Разберитесь в этом вопросе, и вы значительно повысите уровень своей компетенции.
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Что такое cURL в PHP? Встроенные функции и пример GET запроса
Клиент для URL-адресов, cURL, позволяет взаимодействовать с множеством различных серверов по множеству различных протоколов с синтаксисом URL.
0
0
24
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

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

Таким образом, в вашем первом запросе с регистрационным номером без псевдонима предполагается, что столбец RegistrationNumber исходит из единственной таблицы в запросе... с псевдонимом "O". Это то же самое, что написать «ГДЕ РегистрационныйНомер = РегистрационныйНомер» в вашем подзапросе.

Чтобы написать коррелированный подзапрос (это то, что у вас есть... подзапрос, который ссылается на столбец вне себя), вы ДОЛЖНЫ включить псевдоним внешнего запроса. SQL, как я уже сказал, будет использовать псевдоним, если псевдоним не указан, но он будет использовать только таблицу ВНУТРИ того же запроса. Он не будет искать предполагаемый псевдоним таблицы снаружи.

Оглядываясь назад, ответ кажется таким очевидным! Как я мог ожидать, что подзапрос будет ссылаться на таблицу, которая ему не была открыта?! Вероятно, типографика - не рассматривать этот запрос как отдельный запрос или что-то в этом роде... Но теперь я понимаю. Спасибо за откровение.

Ashton Moran 23.05.2019 05:42

Другие вопросы по теме