我有2个单独的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 :(得分:1)
第一个查询将仅显示所有帐户记录的结果,无论帐户是否具有与您的@Year和@Person值匹配的总记录(或者甚至是否与总记录完全匹配)。对于不匹配的记录,它的Total列将为NULL,但所有帐户都会有结果。第二个查询将仅显示总计与年份和人匹配的帐户。如果没有匹配,则帐户记录将根本不会出现在您的结果中。
这两个查询应该更像这样编写(这里不需要子查询):
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 :(得分:1)
通过在外部联接(第二个查询)之后应用WHERE
条件,您可能会从结果集中删除记录。第一个查询将包含ACCOUNTS
表中的每一行。
也就是说,在第一个查询中,返回的表对ACCOUNTS
表中的每个记录至少有一行,其中NULL
s {{1}中没有匹配的数据表。如果Totals
表中有多个匹配项,那么您将获得Totals
的多个行。
第二个查询只返回ACCOUNT
中与参数匹配的行,并且它们必须具有匹配的ACCOUNTS
行。
答案 2 :(得分: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;