2012-04-09 93 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