为什么(以及如何)对 FROM table 的 "implicit" 引用导致此查询中的 return 错误结果?

Why (and how) do "implicit" references to the FROM table cause the return of false results in this query?

我查询的目的是 link 通过 RegistrationNumber 在两个表之间输入 DateTimeIn 和 DateTimeOut。 (数据来自停车利用调查...)

我先尝试了连接,但它无法处理复杂性。例如,一辆车可能有 DateTimeOut(它离开了停车场),但没有 DateTimeIn(它从未停过车,可能是因为停车位都被占用了)。另外,我必须确保第一个 DateTimeIn 得到 linked 到最早的 DateTimeOut 并且每个 DateTime 被 linked 到只有一次。

以下 "nested query" 似乎完成了工作,但返回了误报结果。我不知道这些是如何产生的。即使 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 从哪里来?为什么查询不能处理 "implicit reference" 到 dbo.HobieBeachVehiclesIn?

在查询中,如果您没有为您的列设置别名,则使用别名。假定的别名是具有您正在使用的列的任何 table。这工作正常,只有当您的查询中有多个 table 的同一列时,您才会收到错误...此时您需要别名。

因此,在您的第一个 RegistrationNumber 未使用别名的查询中,RegistrationNumber 列被假定来自查询中唯一的 table...别名为 "O" 的那个。这与在子查询中写入“WHERE RegistrationNumber = RegistrationNumber”相同。

要编写相关子查询(这是您所拥有的……引用自身外部列的子查询),您必须包含外部查询的别名。 SQL,正如我所说,如果没有给出别名,它将假定一个别名,但它只会假定一个 table WITHIN 相同的查询。它不会在外部寻找假定的 table 别名。