この問題を理解するには助けが必要です。以下の 2 つのクエリの違いは何ですか。同じ結果が返されないことはわかっています。
クエリ 1:
SELECT a.col1, b.c1
FROM A a
LEFT JOIN B b
ON a.col1 = b.c1
WHERE b.status = 'Y'
クエリ 2:
SELECT a.col1, b.c1
FROM A a, B b
WHERE a.col1 *= b.c1
AND b.status = 'Y'
最初のクエリ:
SELECT
a.col1, b.c1
FROM
a LEFT JOIN b ON a.col1 = b.c1
WHERE
b.status = 'Y' ;
b.status列 (左外部結合の右側から) がWHERE部分で使用されるため、内部結合と同等です。
SELECT
a.col1, b.c1
FROM
a INNER JOIN b ON a.col1 = b.c1
WHERE
b.status = 'Y' ;
2 番目のクエリは (おそらく) 次のように実行されます。
SELECT
a.col1, b.c1
FROM
a LEFT JOIN b ON a.col1 = b.c1
AND b.status = 'Y' ;
(論理的に)異なるクエリであるため、異なる結果が得られる可能性があります。
これが、この古い構文を使用してはいけない理由の 1 つです。複数の条件や複数の外部結合がある場合など、あいまいな場合があります。
Sybase と SQL Server が密接に関連していることは知っています。は*=SQL Server から削除されましたが、SQL Server 2000 までさかのぼっても、正しく機能しておらず、左結合として解釈されることもあれば、交差結合として解釈されることもありました。Sybase と SQL Server は同じ基本製品に由来するため、これもあなたの問題であり、結果が異なる理由であると思われます。外部結合に暗黙的結合を使用しないでください。正しい答えが確実に得られないためです。
この問題について説明している SQL Server 2000 の Books Online からの直接の引用を次に示します。
以前のバージョンの Microsoft® SQL Server™ 2000 では、 and演算子
WHEREを使用して句で左右の外部結合条件を指定していました。場合によっては、この構文により、複数の方法で解釈できるあいまいなクエリが生成されます。SQL-92 準拠の外部結合が句で指定されているため、このあいまいさは発生しません。*==*FROM
少し遅れて申し訳ありませんが、解決策を見つけました: 古い構文*=では、条件b.Status = 'Y'は左結合 on 句にあるため、最初のクエリで同じ結果を得るためにb.Status = 'Y'、「on」句に移動しました.
これらのクエリは同じように見えます。あなたは、彼らが同じ結果を返さないと言います。例はありますか?
古い結合表記と新しい結合表記が異なるのは、結合する場所を移動した場合です
Select
a.col1,
b.c1
From
A
Left Join
B
On a.col1 = b.c1 And b.Status = 'Y';
これは異なり、古い表記法では簡単に表すことができません (少なくとも Oracle ではそうではありません。Sybase の直接の経験はありません)。
例(ただし、Oracle は(+)の代わりに使用します*=)