2009-06-10 6 views
2

WHERE句が1つのテーブルのpk =他のテーブルのfkをチェックし、結果セットがconnernedされている限り、内部結合と同じになるかどうかは関係ありません。つまり、SQLクエリに次のようなものがある場合:1つのテーブルのpk =他のテーブルのfkのチェックがあると、すべてのタイプの結合が内部結合に還元されますか?

"選択... A左結合B(...)E、F完全外結合G on(A.pk = G.fk) ...ここでA.pk = G.fkとA.pk = B.fkなど... "

上記のクエリでは、AはBに左結合され、GはAに外部結合されますそのfkに。しかし、where句には2つのチェックがあるため、クエリ全体が次のようになります。

"から選択... INNER JOIN B ...(...)E、F INNER G on(A.pk = G.fk)... WHEREなど... " ?

このクエリを要求する理由は、あるテーブルのpk =他のテーブルのfkにあるwhere節と一緒に多くのデカルト型結合があり、クエリが遅くなっていることです。私はデカルト積を、すべてのwhere句を保持しているLeft JoinsまたはすべてのInner Joinsと置き換えることを考えていました。

答えて

1

はい、あなたの場合refernce "where myfield is null"以外のものを含むwhere句の左外部ジョインの右辺は、内部ジョインを作成したことになります。これは、インラインテーブルに一致しないすべてのレコードを含む、その条件を満たすものを除外するためです。他の非内部結合と同じです。それを回避するには、条件を結合に入れます。例(これは内部結合に変換します):

Select field1, field2 from mytable mt 
left join mytable2 mt2 on mt.id = m2.id and mt2.field2 = 'test' 
where mt1.field1 = 'hello' 

は、私はまた、あなたがコメントで言った何かにコメントしたいが、私の応答は次のようになり考え出し:

Select field1, field2 from mytable mt 
left join mytable2 mt2 on mt.id = m2.id 
where mt1.field1 = 'hello' and mt2.field2 = 'test' 

リライトが左を維持するためには、参加します別のコメントには長すぎます。

"選択...内部結合Bをオン(A.id = B.a_id)、C、D、FここでA.id = F.id" to: "選択...内部からA.id = F.a_idのBの結合(A.id = B.a_id)、C、Dの内部結合F:

あなたはこのような構文を組み合わせたくありません。これは維持することが非常に困難になります。事実、古いスタイルのカンマ構文を使用することはお勧めしません。これは、誤ったクロス結合の対象となるためです。だからあなたの例では、私は(少なくとも維持誰かがクロスが事故によって代わりにやったことの参加indended知っている)あなたが現在取得結果セットを取得するために書くでしょう:

Select ... From A 
INNER JOIN B on A.id = B.a_id 
INNER JOIN F on A.id = F.a_id 
CROSS JOIN C 
CROSS JOIN D 

Altenativelyをクロスは偶発で参加する場合は、コードは、に変更します

Select ... From A 
INNER JOIN B on A.id = B.a_id 
INNER JOIN F on A.id = F.a_id 
INNER JOIN C on (fill in the join fields) 
INNER JOIN D on (fill in the join fields) 
3

はい、これは内部結合を取得するラウンドアバウトの方法です。

これはどのように動作するか考えてみましょう:A、次に一致するBまたはヌル、次にすべてのG(A/BおよびG面のヌル)を取り出し、基本的にNull側それに(WHERE句)。だから、INNER JOINはおそらくもっと速いでしょう。しかし、この同じ推移アプローチはそれとして、フル/外部結合では動作しません

SELECT * FROM a INNER JOIN b ON a.id = b.id WHERE b.something = 'awesome' 

SELECT * FROM a INNER JOIN b ON a.id = b.id AND b.something = 'awesome' 

に相当します。この混乱の

一般的な原因は、これはということですジョインしてからフィルタリングします(もちろん、フィルタとオプティマイザによって異なります)。

つまり、実際には内部結合が必要な場合は内部結合を使用します。

編集:PK/FK取引ではないことにも注意してください。WHERE句でON句を本質的に繰り返すと、完全結合/外部結合が内部結合と等価になります。

+0

また、この等価のようにかなっている: 「を選択... A内部から(A.id = B.a_id)にBに参加し、C、D、F A. (Aid = B.a_id)、C、Dインナー・ジョイン・F on A.id = F.a_id " 実際には、主な問題は、DはAではAとAの結合があり、Aは式の前にあるため、Inner Joinは正しく動作して、同じ結果セットを返すように2つのケースを減らしますか? – umar

1

はい、あなたは、単に

"Where PK Is Not Null" or 
"Where FK Is Not Null" 

を追加することができ、これはまた、参加の「外」側から「余分な」レコードを除外するだろう...

関連する問題