2012-04-09 109 views
3

比方说,我有一个表A与列(Alpha,Beta)连接到表B与列(Beta,Delta,Gamma)。我无法解释为什么第一个查询被转换为交叉连接。 (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 

回答

6

顶部查询具有涉及到AB子句ON没有条件。你在做的是将B中的每一行都排在前Delta排序为Gamma的行为Beta行,并将该结果集从A连接到每行。您基本上将B(其将等于B,如果Beta是唯一的)并将其交叉连接到A的子集,因为您尚未指定AB之间的任何直接关系。就像更细节一样,如果你拿任何表并将它加入到没有TableA.SomeColumn = TableB.SomeColumn的任何其他表中,那么你基本上只会从TableB得到可以被限制的完整结果集,然后加入将全部结果集设置为TableA中的每一行,因为它无法限制结合集合加入TableA中的一行。我希望有所帮助。

+0

这是完美的,我期待听到的。我只是很难在文档中发现'陈述'。我也有一种感觉,B没有完全交叉连接(正如你指出的那样,只有唯一的Beta行)给A,但我没有把我的研究拿到很远。 – 2012-04-09 16:32:17