2017-03-16 7 views
0

FROMステートメントで演算子を使用する目的は何ですか?インターネット上で提供されているほとんどの例は、WHERE文に同様の基準を入れることで解決できます。非等価結合を使用する有効なユースケースは何ですか? >、> =、<, <=, <>

例:

SELECT T1.OrderNum, T1.SpecialOfferAppliedDate AS SOAD, T1.SpecialOfferID, T2.StartDate, T2.EndDate 
FROM OrderDetail AS T1 
    INNER JOIN SpecialOffer AS T2 
      ON T1.SpecialOfferID = T2.SpecialOfferID 
WHERE T1.SOAD < T2.EndDate 
    AND T1.SOAD >= T2.StartDate 

EDIT:私は参加非等価で参加しなければならない場所を提供することができます任意のクエリの誰かがあり

SELECT T1.OrderNum, T1.SpecialOfferAppliedDate AS SOAD, T1.SpecialOfferID, T2.StartDate, T2.EndDate 
FROM OrderDetail AS T1 
    INNER JOIN SpecialOffer AS T2 
     ON T1.SpecialOfferID = T2.SpecialOfferID 
     AND T1.SOAD < T2.EndDate 
     AND T1.SOAD >= T2.StartDate 

例は、WHEREステートメントを使用していますか?この時点で、それは関連性があるようです:HUGEテーブルでの個人的な好みまたはパフォーマンスの向上

+1

'left join'のように' where節 'を使うので、最初のフォームを使う方が意味があります'ヌル '値を考慮して)'内部結合'に変換します。 – SqlZim

+1

質問のタイトルは実際の質問とは関係ありません... ...? – Brandon

+1

なぜ 'WHERE'は' ON'よりも有効ですか? – Caleth

答えて

1

SQL 2005以前のバージョンでは、以前はSQL Serverのメンテナンスの方法によっては、以前よりわずかに高速だったと主張することができました。私はスコープをより速く制限し、最大のテーブルを先に進めて、その分の利益を得るために論理的な意味を持っていたので、このようにしていました。

EG:A、B、Cの3つのテーブルがあります。AとBにはDt(日付)フィールドに何百万もの行とインデックスがあります。そして、他のテーブルはわずか数万行しかありませんでした。

Select (columns) 
From a 
    inner join b on a.Id = b.FId 
     and a.Id >= (somedate) 
    inner join c on b.Id = c.FId 

それは一般的に私にできるだけ早く範囲を限定するより多くの意味を行い、エンジンの面で声明「から」実際にSQL Serverで最初に来る:私は多くの時間がこのような何かをするだろう私が読んで見たものからのエンジン。だから私は何百万という何百万という潜在的なすべての可能性を実際に言っていたのですが、内部の結合が常に範囲を戻し、範囲を限定するために一致しなければならないということを知っているだけです。 'Where'句は同じことをしますが、 'From'ステートメントの後に評価されるため、遅くなると結論づけるのが妥当です。

ただし、パフォーマンスと可読性のデベロッパーサークルには常に議論があります。私のようなものだったのであれば:

Select (columns) 
From a 
    inner join b on a.Id = b.FId 
     and a.Id >= (somedate) 
     and a.ocol = (criteria) 
    left outer join c on b.Id = c.FId 
where c.ocol = (criteria) 

を誰かが私に言うことができる:「ねえ男だけかだけWhere句でそれをすべてを置くことについて、それから0.00001ブーストのパフォーマンスを得ています?」パフォーマンスと可読性のバランスをとることがあります。何かが非常に遅れている場合、私は正当にそれがより良い方法かもしれないと言うことができる。しかし、一般的に私はそれを2012年、あるいはおそらく2008年R2、またはそれを読んだので、Microsoftは本質的にそれがもはや本当に時間を節約するとはいえ、より効率的にコンパイルするエンジンを作り直しました。あなたがしたい場合けれどもそれを自分でテストすることができます。

を実行し、このSQL Management Studioを上:

SET STATISTICS TIME ON。

そして、あなたはこのようなものが表示されます:メッセージタブで

SQL Server parse and compile time: 
    CPU time = 0 ms, elapsed time = 2 ms. 

SQL Server Execution Times: 
    CPU time = 0 ms, elapsed time = 0 ms. 

SQL Server Execution Times: 
    CPU time = 0 ms, elapsed time = 2 ms. 

SQL Server Execution Times: 
    CPU time = 0 ms, elapsed time = 0 ms. 

SQL Server Execution Times: 
    CPU time = 0 ms, elapsed time = 8 ms. 

を。もちろん、ビューパネルからより重い手による 'Client Statistics'タブを実行して、さらに詳細を表示することもできます。これは、スコープをより速く制限するためにエンジンの実行をより効率的に使用するために多くの人が採用している文法的なトリックだと言えます。しかし、このような改造はそれ以上の改善をもたらさないかもしれません。私はまだそれを使用していますが、自分自身でコーディングすると物事に慣れてしまいます:)

0

INNER JOINは、使用すべきANSI構文です。可能であれば、WHEREへの追加を避けるのが最善の方法です。

また、特に多くのテーブルに参加したときには、一般的にはより読みやすく、必要が生じたときはいつでも容易にOUTER JOINに置き換えることができます。

パフォーマンス面では、違いはありません。

+0

どちらのクエリも明示的な '内部結合 'を使用しています –

+0

yeap申し訳ありませんが、これに対応するために速くでした...質問に一致するように編集 – Lostblue

+0

私はwhereのステートメントに条件を入れるのを避けるべきですか?それは単に個人的な好み/個人的な可読性ですか?私にとっての基準は常に論理的にWHEREに置かれていますが、現在WHERE文が複雑になっている問題に遭遇したことはありません。 –

1

すべてすべての作業を行っているWHERE文で結合を書き直すことができます。

SELECT table1.cols ..., table2.cols ... 
FROM table1 
JOIN table2 ON TRUE 
WHERE table1.id = table2.id 

UNION SELECT cols, null ... -- for LEFT or FULL JOIN 
FROM table1 WHERE id NOT IN (SELECT id FROM table2) 

UNION SELECT null ..., cols -- for RIGHT or FULL JOIN 
FROM table2 WHERE id NOT IN (SELECT id FROM table1) 

あなたはWHERE

を使用する場合LEFT | RIGHT | FULL JOIN例は、私が個人的にずっとJOIN ... ONに質問で関係なく、WHERE句を表現することを好む、より扱いにくいか注意してください。 "この注文に適用される特別オファー"と呼ぶことができるこの例では、 "この注文に適用する"にはアイデンティティと時間的要素の両方があります。

1

これはすべて可読性と明瞭性に関するものです。

2つのテーブルを結合すると、その結合のロジックを1か所に保持することが理にかなっています。あなたの例では、ロジックマッチングレコードは、外部キーの関係(T1.SpecialOfferID = T2.SpecialOffID)と購入日とスペシャルオファーの両方に依存します。日付ロジックは結合に不可欠であるように見えます。その日付範囲内に収まる一致のみを検索したいだけです。

"where"句では、注文ロジックの値、特別オファーの作成者、その他のものに影響を与えない他の制限があります。

通常、どの句が結合の固有の部分であり、データセットの細分化であるかは、解釈の問題です。実際には、2つの使用法は同等です。

「非等価」部分は - 私が信じる - それは結合を定義する方法にのみ関連します。あなたの例では、 "IDに一致するレコードも日付範囲内に収まる必要があります"という論理があります。

結合ステートメントに比較を含めるユースケースは、ビジネスドメインは、結合条件全体が満たされた場合にのみ、これらのレコードが一緒に属していることを示します。

where句に比較を含めるというユースケースでは、必要な結果を絞り込むことができますが、ビジネスドメイン内のどのレコードが「一緒に属しているか」は定義されていません。

+0

それでは、2つの使用法が同等であると言って、1つを別のものに使用する特殊なユースケースはありません。 –

+1

私は自分の答えを更新しました。実行の観点から見ると、それらは同等です - それは本当にコーディングスタイルのものです –

0

オフハンド私は、不等式を含む関係によって自然に関連する2つのテーブルの例は考えられません。私が書いたかもしれない質問を考える能力はまだありません。私は年齢で人をランク付けしたいとします。簡単にするために、結びつきを仮定しないでください。

select p.name, count(*) as age_rank 
from people p inner join people p2 on p2.birth_date <= p.birth_date 
group by p.name 

分析機能のような高度なSQL機能では、自己結合機能を持つこれらのトリックの多くは必要なくなりました。

fromwhereの間で論理条件を移動することに焦点を当てていたようです。外部結合を使用し始めると、クエリがもはや意味論的に同一ではなくなるため、自由度はなくなります。

+0

この問題は、生年月日で人物をソートすることで解決できます。一見不必要な自己結合を行う代わりに。私はFROMに基準を入れることがより有益/必要であるユースケースを見つけようとしています。あなたの質問は私のやり方よりも多くの利点がありますか? –

+0

あなたは確かに結果を並べ替えてランキングを見ることができますが、それはクエリ自体が内部的に使用できるデータを提供しません。コンセンサスでは、結合に関連するロジックのみを結合条件に入れます。オプティマイザは、一般に、必要に応じて実行計画自体を整理するのに適しています。しかし、それが利益をもたらすと私が考えることができる唯一の理由は最適化です。上記の外部結合についての私の注意を参照してください。 – shawnt00

関連する問題