3

假设我有一个带有列(Alpha,Beta)的表 A,它链接到带有列(Beta,Delta,Gamma)的表 B。我无法解释为什么第一个查询被转换为交叉连接。(A.Alpha、A.Beta 和 B.Delta 是唯一键。B.Beta 查找 A.Beta)。

如果我做这样的选择:

SELECT A.Alpha, B_Alias.Gamma FROM A 
LEFT JOIN B as B_Alias ON B_Alias.Delta = (
  SELECT TOP 1 B_Alias.Delta FROM B 
  WHERE B.Beta = B_Alias.Beta
  ORDER BY B.Gamma desc)
where A.Alpha = 1

结果是很多行,A.Alpha 总是等于选择的单行,B_Alias.Gamma 有每个 Gamma。如果我取出A.Alpha = 1,那么它是一个完整的交叉连接。查询作者的尝试是获取与 A 关联的最新 B 列(如果存在)。我使用以下方法修复了它以使其工作。我只是想知道是否有人可以解释为什么上述方法会这样工作。

-- This is the correct query
SELECT A.Alpha, B_Alias.Gamma FROM A 
-- Actually join the A and B tables
LEFT JOIN B on B.Beta = A.Beta and B.Delta = (
  -- Only get the Most Recent B for any given A
  SELECT TOP 1 B.Delta FROM B 
  WHERE B.Beta = A.Beta
  ORDER BY B.Gamma desc)
where A.Alpha = 1
4

1 回答 1

6

顶部查询在与相关的ON子句中没有条件。您正在做的是从其中的每一行中获取其所在行的顶部排序,并将该结果集加入到每一行中。您实际上是在获取(这将等于if is unique) 的一个子集并将其交叉加入,因为您没有指定and之间的任何直接关系。ABBDeltaGammaBetaABBBetaAAB

更详细一点,如果您将任何表加入到任何其他没有的表中TableA.SomeColumn = TableB.SomeColumn,那么您基本上只会从中获得完整的结果集TableB,然后将完整的结果集加入每一行in TableA,因为它没有办法限制加入的结果集在TableA. 我希望这会有所帮助。

于 2012-04-09T16:07:59.070 回答