2012-10-03 220 views
1

我有2個獨立的SQL查詢和我無法弄清楚如何不同:SQL查詢語句

SELECT A.AccountName, 
     T.Total 
FROM ACCOUNTS A 
     LEFT OUTER JOIN (SELECT * 
         FROM Totals 
         WHERE PersonID = @PersonID 
           AND Yr = @Year) T 
     ON A.AccountID = T.AccountID 
ORDER BY AccountName 

SELECT A.AccountName, 
     T.Total 
FROM ACCOUNTS A 
     LEFT OUTER JOIN (SELECT * 
         FROM Totals) T 
     ON A.AccountID = T.AccountID 
WHERE PersonID = @PersonID 
     AND Yr = @Year 
ORDER BY AccountName 

任何幫助將不勝感激。

+0

@MartinSmith你有一個自動縮進SQL的工具嗎?這是一個糟糕的快速編輯。 – NullUserException

+0

@NullUserException - 是的。我有一個SQL漂亮打印機的副本。 [這裏有一個在線版本](http://www.dpriver.com/pp/sqlformat.htm) –

+0

沒有。只需在 –

回答

1

第一個查詢將只顯示所有帳戶記錄的結果,無論帳戶是否具有與您的@Year和@Person值相匹配的總記錄(或者甚至根本不符合總記錄)。對於不匹配的記錄,Total列的值爲NULL,但所有帳戶都會有結果。第二個查詢將僅顯示總計與年份和人員匹配的帳戶。如果沒有匹配,則帳戶記錄根本不會顯示在您的結果中。

而且2個查詢確實應該寫更多像這樣(沒有必要在這裏的子查詢):

SELECT A.AccountName, T.Total 
FROM ACCOUNTS A 
LEFT JOIN Totals T 
     ON A.AccountID = T.AccountID AND T.PersonID = @PersonID AND T.Yr = @Year 
ORDER BY AccountName 

SELECT A.AccountName, T.Total 
FROM ACCOUNTS A 
LEFT JOIN Totals T ON A.AccountID = T.AccountID 
WHERE T.PersonID = @PersonID AND T.Yr = @Year 
ORDER BY AccountName 

上面的代碼在功能上等同於原件。

最後,這聽起來像你可能想要更多的東西是這樣的:

SELECT A.AccountName, T.Total 
FROM Accounts A 
INNER JOIN Totals T ON T.AccountID = A.AccountID 
WHERE T.PersonID = @PersonID AND T.Yr = @Year 

在此查詢,不要緊,你把你的新年和人物的條件。查詢結果將具有相同的結果:僅當帳戶記錄與總計記錄與期望的年份和人員匹配時纔會顯示該帳戶記錄。不匹配的帳戶根本不會顯示在結果中。

1

通過在外連接(第二個查詢)之後應用WHERE條件,您可能會從結果集中刪除記錄。第一個查詢將包括ACCOUNTS表中的每一行。


也就是說,在第一個查詢,返回的表將有至少一排在ACCOUNTS表中的每個記錄,與NULL S其中有在Totals表中沒有匹配的數據。如果Totals表中存在多個匹配項,那麼您將獲得多行ACCOUNT

第二個查詢將僅返回與參數匹配的ACCOUNTS中的行,並且它們必須具有匹配的Totals行。

+0

好吧,輸出結果如何? –

+0

用結果集的描述更新了我的答案。 –

0

無論何時您爲OUTER JOIN表放置簡單子句,都必須在測試條件之前測試外部表是否存在,否則實際上將外部聯接轉換爲內部聯接。在你的情況下:

-- original 
SELECT A.AccountName, T.Total 
FROM ACCOUNTS A 
LEFT OUTER JOIN (SELECT * 
    FROM Totals 
    WHERE PersonID = @PersonID 
    AND Yr = @Year 
) T ON A.AccountID = T.AccountID 
ORDER BY AccountName; 

-- modified with same result 
SELECT A.AccountName, T.Total 
FROM ACCOUNTS A 
LEFT OUTER JOIN Totals T ON A.AccountID = T.AccountID 
WHERE (1=2 -- syntactic sugar 
    OR (T.AccountID IS NULL) -- this prevents outer joined rows to be excluded 
    OR (T.PersonID = @PersonID AND T.Yr = @Year) -- original filter 
) 
ORDER BY AccountName;