Почему (и как) «неявные» ссылки на таблицу 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?

Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
24
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

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

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

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

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

Ashton Moran 23.05.2019 05:42

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