-3

次のようなクエリがあります。

SELECT *
FROM TableA a
LEFT JOIN TABLEB b
ON a.ColA = b.ColA
WHERE b.Col1 IS NULL 
OR (b.Col1 = A AND b.Col2 = B AND b.Col3 BETWEEN @StartDate AND @EndDate)

TableA からすべての行が返されることを期待しているのに、クエリの日付部分が結果セットを台無しにして 3 行しか返さないため、奇妙な結果セットが得られます。これは、datetime フィルターを削除して他の 2 つのフィルターをそのままにしておくと、正しい結果が得られるためです。

これは「予期しない動作」のように思えますが、なぜこれが起こっているのかを論理的に説明することはできません。

4

3 に答える 3

3

構文エラーにもかかわらず....

where句のすべてのロジックがテーブルBにあるため、右結合を実行する必要があります。

SELECT * 
FROM TABLEB b 
RIGHT JOIN TABLEA a on a.SomeId = b.SomeId
WHERE b.Col1 IS NULL  OR (b.Col1 = A AND b.Col2 = B AND b.Col3 BETWEEN @StartDate AND @EndDate) 

しかし、これはあなたが本当に望んでいるものかもしれません...

SELECT *  
FROM TableA a  
LEFT JOIN TABLEB b on b.SomeId = a.SomeId and b.Col1 = A AND b.Col2 = B AND b.Col3 BETWEEN @StartDate AND @EndDate  
WHERE b.Col1 IS NULL 
于 2012-05-14T15:44:46.310 に答える
0

あなたのSQLはこのように書く方が良いでしょう:

SELECT *
FROM TableA a
LEFT JOIN TABLEB b ON a.col1 = b.col2
WHERE (b.col3 IS NULL) or (b.Col3 BETWEEN @StartDate AND @EndDate)

これb.Col1 = A AND b.Col2 = Bは、左結合ステートメントの正しい構文であるため、LEFT JOIN ピースに移動する必要があります。

したがって、上記の SQL は次のように変換できます: tableA からのすべての行と、tableA からの col1 が等しい tableB からの行を選択し、tableB からの col3 で結果をフィルター処理します。 @StartDate および @EndDate。

それが役に立てば幸い。

よろしくお願いします。

于 2012-05-14T15:48:00.510 に答える
0

この問題を修正し、それらを派生テーブルに変更して、すべての述語が結合前に適用されるようにしました。

ご協力いただきありがとうございます。

于 2012-05-14T17:24:19.557 に答える