あなたの元の質問を読んだところ、次の基準のいずれかを満たす従業員を見つけたいということです。
- 彼らのスキル ID は 3 と 4 と 5 です
- 彼らのスキル ID は 4 AND 5 AND 6 です
(または両方)。この場合、相関サブクエリを使用して次のようなことをしたいと思うでしょう:
select *
from employee e
where ( exists ( select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 3 )
and exists ( select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 4 )
and exists ( select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 5 )
)
OR ( exists ( select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 4 )
and exists ( select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 5 )
and exists ( select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 6 )
)
ただし、2 つのターゲット スキル セット { 3, 4, 5 } と { 4, 5, 6 } には共通のサブセット { 4 , 5 } があるため、単純化できます。リファクタリング、私たちは得る
select *
from employee e
where exists ( select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 4 )
and exists ( select * from employee_skill es3 on es3.empid = e.empid and es3.skillid = 5 )
and exists ( select * from employee_skill es3 on es3.empid = e.empid and es3.skillid in ( 3 , 6 ) )
別の手法は、次を使用することleft join
です。
select *
from employee e
left join employee_skill es3 on es3.empid = e.empid and es3.skillid = 3
left join employee_skill es4 on es4.empid = e.empid and es4.skillid = 4
left join employee_skill es5 on es5.empid = e.empid and es5.skillid = 5
left join employee_skill es6 on es6.empid = e.empid and es6.skillid = 6
where es4.empid is not null
and es5.empid is not null
and ( es3.empid is not null
OR es6.empid is not null
)
この後者のアプローチleft join
には、特定の従業員/スキルの組み合わせがデータ モデル内で一意であるという暗黙の前提が含まれています。そうでない場合、このアプローチではselect distinct
、結果セットで重複した行が得られないように を使用する必要があります。