2011-01-14 4 views
11

主キー列に2つの単純な表を結合し、等価条件を追加する場合、これは結合自体またはwhere句で実行できます。from節またはwhere節でequi joinを実行する方がよいでしょうか?

例えば、以下は等価である。 私の質問です - あるスタイルを他のスタイルよりも使用する理由はありますか?

SELECT * 
FROM A 
INNER JOIN B ON A.A_ID = B.A_ID 
      AND A.DURATION = 3.00 

... VS:

SELECT * 
FROM A 
INNER JOIN B ON A.A_ID = B.A_ID 
WHERE A.DURATION = 3.00 
+2

私はそれが参加し続け、より複雑なクエリのために仮定し、このクエリ – AJM

答えて

9

スタイルの問題です。一般的に、FROM句に結果セットの "形状"を定義する条件(つまり、各テーブルのどの行を結合して結果を生成するかを制御する条件)を入れたいのですが、フィルタ結果セットはWHERE節になければなりません。 INNER JOINの場合、効果は同じですが、OUTER JOIN(LEFT、RIGHT)が関与すると、より明確に感じられます。


最初の例では、「このことは表Bと何が関係していますか」と尋ねられました。私がJOINでこの奇妙な状態に遭遇したとき。一方、興味のない場合はFROM句(およびすべてのJOIN)をスキップし、行がWHERE句で返されるかどうかを判断する条件を参照することができます。

1

そのスタイルの問題。オプティマイザは最適な処理を行います。

3

SQL Server 2000+の場合、これらのクエリのそれぞれのクエリプランは、インテンシカルなので、パフォーマンスも変わりません。

これを確認するには、SSMSを使用して、クエリを実行する前にCTRL + Mを押す各クエリの実際の実行計画を表示します。結果ペインには、実行計画を示す追加のタブが表示されます。この場合、2つの計画は同じであることがわかります。

6

これは重要なJOINのタイプです。
INNER JOINを処理しているため、どちらのバージョンのクエリでも同じ実行計画が使用されますが、違いはありません。

外側を扱うがJOINの場合:WHERE基準はザが行われるJOIN 後に適用されているので(IE LEFT、RIGHT)、2つのバージョン間巨大差があります。条件がON句で指定されている場合、条件はより前に適用されます。 JOINが行われ、結果セット間に大きな違いが生じる可能性があります。

10

一般に、意味上の違いはありません。

ただし、できるエッジケースが1つあります。以下に示すように、(非推奨の)GROUP BY ALL構文がクエリに追加されている場合。

DECLARE @A TABLE(A_ID INT, DURATION DECIMAL(3,2)) 
INSERT INTO @A VALUES(1,2.00) 

DECLARE @B TABLE(A_ID INT) 
INSERT INTO @B VALUES(1) 

/*Returns one row*/ 
SELECT * 
FROM @A A 
INNER JOIN @B B ON A.A_ID = B.A_ID 
WHERE A.DURATION = 3.00 
GROUP BY ALL A.A_ID, A.DURATION, B.A_ID 

/*Returns zero rows*/  
SELECT * 
FROM @A A 
INNER JOIN @B B ON A.A_ID = B.A_ID AND A.DURATION = 3.00 
GROUP BY ALL A.A_ID, A.DURATION, B.A_ID 
0
--Samples for time of join wheather can we write condition at where or ON 
create table #emp(id int ,teamid int) 
create table #team(tid int,name char(2)) 
insert into #emp values(1,1) 
insert into #emp values(2,1) 
insert into #emp values(3,2) 
insert into #emp values(4,0) 

insert into #team values(1,'A') 
insert into #team values(2,'B') 
insert into #team values(3,'C') 

--select * from #emp 
--select * from #team 

--on inner join => there is no difference in Query Exc. Plan 
--select * from #emp e join #team t on e.teamid=t.tid where e.teamid=2 
--select * from #emp e join #team t on e.teamid=t.tid and e.teamid=2 


/*on outetr join see the differnence If dealing with an OUTER JOIN (IE: LEFT, RIGHT), 
there is a huge difference between the two versions because the WHERE criteria is applied after the JOIN is made. 
If the criteria is specified in the ON clause, the criteria is applied before the JOIN is made which can made a considerable difference 
between the result sets.*/ 
select * from #emp e left join #team t on e.teamid=t.tid 
select * from #emp e left join #team t on e.teamid=t.tid where e.teamid=2 
select * from #emp e left join #team t on e.teamid=t.tid and (e.teamid=2 or t.tid=1) and t.name='A' 


drop table #emp 
drop table #team 
+0

の部分の間でスクロール避け同じ場所に任意の条件は、あなたがすぐに – Siva

+0

物事をGRAPするのに役立ちます、以下の詳細な説明を参照してください。私は説明を見ません。2年前にOMG Poniesが言ったことのちょうど繰り返し。 – Leigh

関連する問題