1

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 

どんな助けでも大歓迎です。

4

3 に答える 3

1

最初のクエリは、アカウントに @Year および @Person の値に一致する Total レコードがあるかどうか (または Total レコードにまったく一致しないかどうか) にかかわらず、すべての Account レコードの結果のみを表示します。一致しないレコードの [合計] 列は NULL になりますが、すべてのアカウントの結果が得られます。2 番目のクエリは、合計が年と人に一致するアカウントのみを表示します。一致しない場合、アカウント レコードは結果にまったく表示されません。

そして、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

このクエリでは、Year および Person 条件をどこに置くかは問題ではありません。クエリはどちらの方法でも同じ結果になります。アカウント レコードは、必要な年と人を持つ合計レコードと一致する場合にのみ表示されます。一致しないアカウントは結果にまったく表示されません。

于 2012-10-03T16:41:18.363 に答える
1

外部結合 (2 番目のクエリ) の後に条件を適用するとWHERE、結果セットからレコードが除外される可能性があります。最初のクエリには、ACCOUNTSテーブルのすべての行が含まれます。


つまり、最初のクエリでは、返されるテーブルには、テーブル内のすべてのレコードに対して少なくとも 1 つの行がACCOUNTS含まNULLれ、テーブル内に一致するデータがない場合は s が含まれTotalsます。Totalsテーブルに複数の一致がある場合は、そのACCOUNT.

2 番目のクエリはACCOUNTS、パラメーターに一致する行のみを返し、一致するTotals行が含まれている必要があります。

于 2012-10-03T16:41:22.663 に答える
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;
于 2012-10-03T16:58:22.760 に答える