为什么(以及如何)对FROM表的“隐式”引用导致此查询中返回错误的结果?

时间:2019-05-22 14:46:23

标签: tsql ssms

查询的目的是通过RegistrationNumber在两个表之间链接DateTimeIn和DateTimeOut条目。 (数据来自停车利用率调查...)

我首先尝试了一个连接,但是它无法处理复杂性。例如,某辆车可能有一个DateTimeOut(它退出了停车区),但没有DateTimeIn(它从未停过,可能是因为托架都被占用了)。另外,我必须确保第一个DateTimeIn链接到最早的DateTimeOut,并且每个DateTime仅链接一次。

以下“嵌套查询”似乎可以完成工作,但是返回了假阳性结果。我不知道这些是如何产生的。即使没有RegistrationTime的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的“隐式引用”?

1 个答案:

答案 0 :(得分:0)

在查询中,当您不对列进行别名时,将使用别名。假定别名是包含您正在使用的列的任何表。这可以很好地工作,并且只有在查询中有多个表具有相同列的情况下,您才会收到错误提示。在这一点上,您需要使用别名。

因此,在您的第一个查询中没有为RegistrationNumber加上别名的情况下,假定RegistrationNumber列来自查询中的唯一表……一个别名为“ O”的表。这与在子查询中写入“ WHERE RegistrationNumber = RegistrationNumber”相同。

要编写一个相关的子查询(这就是您所拥有的...一个子查询,它引用自身外部的列),您必须包括外部查询的别名。如前所述,如果未指定别名,SQL将采用别名,但仅假设在同一查询中存在一个表。它不会在外面寻找假定的表别名。