スイッチポートからMACアドレスを取得してデータベースに入れるスクリプトを作成しました。それをインポートテーブルに挿入して、後で実際のテーブルにコピーします。大丈夫だ。現在、新しいMACアドレスを見つけるためのクエリを書いています。したがって、インポート先のテーブルにないインポートテーブルの行が必要です。左外部結合は意味があります。
select *
from SwitchportMac_import i
left outer join SwitchportMac sm
on sm.switch = i.switch and sm.port = i.port and sm.mac = i.mac
これは、i
と一致するsm
の行も返します。確かに、where sm.id is null
だが、私は戸惑う。
だからどちらか:
最初の場合は、DDLをダンプしてそれを理解しますが、2番目の場合は怖いです。私を混乱させるためだけに外側のキーワードは存在しますか?
LEFT JOIN
とLEFT OUTER JOIN
は同義語です。申し訳ありませんが、オプション2のように聞こえます:-)
「外部」結合(一致しない行を保持)は、「内部」(そうではない)とは対照的です。
外部結合には3つのフレーバーがあります。左、右、フル(どの一致しない行を保持するかによって異なります)。
SQLには他のタイプの結合(左/右の反セミ結合など)の直接結合構文がないため、OUTER
キーワードを文法でオプションにすることは、あいまいさはありません。
LEFT ANTI SEMI JOIN
は、LEFT OUTER
が期待していたように聞こえます。 さまざまな方法 で実装できます。通常NOT EXISTS
が推奨されますが、LEFT OUTER JOIN
をIS NULL
と組み合わせて使用して、一致しないものだけを保持することができます。
これはすべて、ドキュメントの " Join type "セクションで確認されています
LEFT [ OUTER ]
結合条件を満たさない左のテーブルからのすべての行が結果セットに含まれ、他のテーブルからの出力列が内部から返されるすべての行に加えてNULL
に設定されることを指定します参加する。
[OUTER]
を囲む角括弧は、これがオプションであることを意味しますが、同じ定義が適用されます。
これは、EXISTSで相関サブクエリを使用して、必要なものを取得するための私の好ましい方法です。スイッチ、ポート、およびMACの両方のテーブルにインデックスがあると仮定すると、これも良好なパフォーマンスになるはずです。
SELECT *
FROM SwitchportMac_import i
WHERE NOT EXISTS (
SELECT TOP (1) 1
FROM SwitchportMac sm
WHERE sm.switch = i.switch
and sm.port = i.port
and sm.mac = i.mac
)
switchportMac_import i LEFT OUTER JOIN SwitchportMac smから
これは、smと一致するiの行を返します。
正しい。これが、LEFT [OUTER] JOINが行うこととまったく同じです。「右」テーブル(sm)で一致する行を見つけることができるかどうかにかかわらず、「左」テーブル(i)でeverythingを取得します。
「新しい」アイテム(「右」ではなく「左」のテーブルに表示されるもの)を取得するには、必要な場合その「is null」テストを含める同様に =。これは一般に「除外結合」と呼ばれます。
where sm.id is null
は、結合に存在しない行を照合するために必要です。
左結合は常にOUTER
であるため、委員会によって発明された構文糖衣です。彼らはあなたや他の人を前もって混乱させることを考えているところです。あなたはばかではありません、混乱は計画通りに実装されました。
LEFT結合は、「左からすべての行を取得する、つまり前のテーブル、つまりSwitchportMac_importを取得する」と言います。そのテーブルのすべての行を必要とせず、一致しない行のみを必要とします。
IS NULLを追加すると機能します。ここではNOT EXISTSの方がニーズに適していると思います。