仮定の状況: 私は特注看板製作会社で働いており、一部のクライアントは、現在使用しているよりも多くの看板デザインを提出しています。使用されたことのない標識を知りたい。
関連する 3 つのテーブル:
表 A - 会社の標識
sign_pk(ユニーク) | company_pk | sign_description
1 --------------------1 ---------------- 小
2 ---------- -----------------------1 ---------------- 大
3 -------------------- 2 ---------------- ミディアム
4 --------------------2 ---------- ------ ジャンボ
5 --------------------3 ---------------- バナー
表 B - 会社の所在地
company_pk | company_location (一意)
1 ------|------ 987
1 ------|------ 876
2 ------|------ 456
2 ------|------ 123
表 C - 場所の標識 (少し大げさですが、各行には 2 つの標識を含めることができ、会社の場所から場所の標識への 1 対多の関係です)
会社の場所 | フロントサイン | back_sign
987 ------------ 1 ------------ 2
987 ------------ 2 -------- ---- 1
876 ------------ 2 ------------ 1
456 ------------ 3 ---- -------- 4
123 ------------ 4 ------------ 3
したがって、a.company_pk = b.company_pk および b.company_location = c.company_location です。私が試して見つけたいのは、sign_pk 5 がどの場所にもないことを照会して取得する方法です。すべてのテーブルに何百万もの行があるため、すべての front_sign および back_sign 値に対して各 sign_pk をクエリすることは、少し非現実的です。テーブル a は sign_pk と company_pk でインデックス付けされ、テーブル b は両方のフィールドでインデックス付けされ、テーブル c は会社の場所のみでインデックス付けされます。私が書き込もうとしている方法は、「各標識は会社に属しているため、その標識に関連付けられている会社に属する場所のいずれかで、前面または背面の標識ではない標識を見つけてください」という行に沿っています。
私の当初の計画は次のとおりでした。
Select a.sign_pk
from a, b, c
where a.company_pk = b.company_pk
and b.company_location = c.company_location
and a.sign_pk *= c.front_sign
group by a.sign_pk having count(c.front_sign) = 0
前の記号を実行してから後ろの記号を繰り返すだけですが、 c は外部結合の内部メンバーであり、内部結合でもあるため、実行されません。
この全体はかなり複雑ですが、誰かがそれを理解できるなら、私はあなたの親友になります.