web-dev-qa-db-ja.com

SQL Server LEFT JOINおよびWHERE句

ここに私のコードがあります

SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN Table2 ON Table1.ID = Table2.ID
WHERE Table1.ID = 12 AND Table2.IsDefault = 1

この問題は、Table2がnullの場合に発生するため、クエリは何も返しません。

クエリの最後の部分を残す方法AND Table2.IsDefault = 1オプション?

ORを使用してクエリを短絡しようとしましたが、C#とは異なる動作をすることがわかりました

16
Felipe Miosso
SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN Table2 
ON Table1.ID = Table2.ID AND Table2.IsDefault = 1
WHERE Table1.ID = 12
29
t-clausen.dk
_ AND COALESCE(Table2.IsDefault,1) = 1
_

コメントを読んで、あなたの最善の解決策は実際に条件を結合に移動することのように見えます:

_SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN Table2 ON Table1.ID = Table2.ID AND Table2.IsDefault = 1
WHERE Table1.ID = 12 
_

OUTER結合であるため、一致が失敗した場合でもTable1情報を保持し、「Table2は常に1エントリを返す」というステートメントがあれば、条件を移動して追加の結合結果をフィルタリングするリスクはありません。 WHERE句に条件を配置するとsameの結果が得られます。

ConidtionをON句に移動する理由は、COALESCE()ISNULL()、およびORがすべてインデックスの問題を引き起こすためです。 ON句の条件では、これらのいずれも必要ないため、最終的にはより良い実行計画が必要です。

2
Joel Coehoorn

これを試して :

SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN Table2 ON Table1.ID = Table2.ID
WHERE Table1.ID = 12 AND isnull(Table2.IsDefault,1) = 1

あなたはほとんどそこにいた:-)

1
Laurent S.
SELECT ID, Name, Phone FROM Table1 
  LEFT JOIN Table2 ON Table1.ID = Table2.ID
  WHERE Table1.ID = 12 
    AND (Table2.IsDefault IS NULL OR Table2.IsDefault = 1);

サブクエリを使用して、表2と結合する前に表2の結果をフィルターします。

SELECT ID, Name, Phone 
FROM Table1 
LEFT JOIN (SELECT * FROM Table2 WHERE IsDefault = 1) AS Table2 ON Table1.ID = Table2.ID
WHERE Table1.ID = 12
0
hargobind