SQL1:
select t1.f1,t2.f2
from t1
left join t2 on t1.f1 = t2.f2 and t1.f2=1 and t1.f3=0
SQL2:
select t1.f1,t2.f2
from t1
left join t2 on t1.f1 = t2.f2
where t1.f2=1 and t1.f3=0
違いはwhereとon句ですが、同じ戻り結果がありますか?そして、違いは何ですか? DBMSはそれらを同じ方法で実行しますか?ありがとう。
where
句は結果セット全体に適用されます。 on clause
は問題の結合にのみ適用されます。
提供されている例では、結合の内側のフィールドに関連するすべての追加条件-この例では、2つのクエリは実質的に同一です。
ただし、結合のouter側のテーブルの値に条件を含めた場合は、大きな違いが生じます。
あなたはこのリンクからもっと得ることができます: http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause
例えば:
select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 and t2.f4=1
select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 where t2.f4=1
-異なることを行う-前者はf2が1であるt2レコードへの結合を残し、後者は事実上t2への内部結合に戻されました。
最初のクエリは、2番目のクエリよりも結合条件がより具体的であるため、2番目のクエリよりも高速です。where句でフィルタリングするレコードを返すことは意味がありません(それらをまったく返さない方が良いでしょう。query1 )
とにかく、それは本当にクエリオプティマイザーによって異なります。
以下を見てください:
2つのクエリは[〜#〜] not [〜#〜]同一です。
Mark Bannisterは、where
句が結果セット全体に適用されるが、on clause
が結合に適用されることを指摘したのは正解でした。
あなたの場合、SQL 1 LEFT JOIN条件の場合、フィルターは右側で結合されますが、左側は常にWHEREフィルターの前に返されます。 WHERE条件がないため、常にすべてのt1が返されます。
SQL 2では、LEFT JOIN条件が右側に表示される結果をフィルタリングしますが、再びすべてのt1が返されます。ただし、今回はWHERE条件により、t1の一部のレコードが除外される場合があります。
INSERT INTO `t1` (`f1`,`f2`,`f3`) VALUES (1,1,1); INSERT INTO `t2` (`f3`) VALUES (1);
それらは異なるロジックをポイントするため、クエリはそれに基づいて作成する必要があり、それにより大きなパワーと柔軟性が得られます。
ただし、INNER JOINは同じ結果を返すため、オプティマイザを確認してください。
1)
SQL1: select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 **and** t1.f2=1 and t1.f3=0
この場合、パーサーはこれら3つの条件でt1の各行とt2の各行をチェックします。より速い結果を得る。
2)SQL2: select t1.f1,t2.f2 from t1 left join t2 on t1.f1 = t2.f2 **where** t1.f2=1 and t1.f3=0
この場合、結合は最初の条件のみを取り、結合から得られた結果はそれらの2つの条件でフィルタリングされます。そして、最初のクエリよりも時間がかかります。
あなたはこのリンクからもっと得ることができます: http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause
リレーショナル代数を使用すると、WHERE句とINNER JOINの述語を交換できるため、WHERE句を使用したINNER JOINクエリでも、オプティマイザによって述語を再配置できるため、JOINプロセス中に述語を除外できます。
できるだけ読みやすい方法でクエリを記述することをお勧めします。
これには、INNER JOINを比較的「不完全」にすることや、いくつかの基準をWHEREに置くことで、フィルタリング基準のリストをより簡単に保守できるようにすることが含まれる場合があります。
あなたはこのリンクからもっと得ることができます: http://ask.sqlservercentral.com/questions/80067/sql-data-filter-condition-in-join-vs-where-clause
たとえば、次の代わりに:
SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
ON ca.CustomerID = c.CustomerID
AND c.State = 'NY'
INNER JOIN Accounts a
ON ca.AccountID = a.AccountID
AND a.Status = 1
書く:
SELECT *
FROM Customers c
INNER JOIN CustomerAccounts ca
ON ca.CustomerID = c.CustomerID
INNER JOIN Accounts a
ON ca.AccountID = a.AccountID
WHERE c.State = 'NY'
AND a.Status = 1
しかし、それはもちろん異なります。