Схема ниже. По сути, в нижней части находятся навыки, затем рабочие места, а затем кандидаты (пока игнорируйте компании). Каждый навык может быть связан с несколькими заданиями, а задание может иметь несколько умений. Каждая работа относится к одному кандидату, который может иметь (имел) несколько (исторических) вакансий, каждая с одной компанией.
Я просто не могу понять запросы, чтобы найти всех кандидатов с навыком X.
Фактически, это становится сложным, потому что X - это не просто один навык, это может быть несколько навыков, с булевыми операторами, такими как
найти всех кандидатов с (skill = "C ++" и skill = "UML") и NOT (skill = "Python")
Где (skill="C++" and skill="UM"L) and NOT(skill="Python")
часть является строкой, которая должна содержать действительный подзапрос SQl, но я не могу понять остальную часть запроса.
[Обновить], когда я сказал «такой как», я не имел в виду именно эту строку запроса. Я пытаюсь найти способ обработать любую строку запроса навыков. Например, skill=VB
или skill=VB and skill=C
или skillFreeRTOS and not skill=Windows
Кстати, схема появилась из ответа на этот вопрос выглядит хорошо для меня, но ...
3 ответа
найти всех кандидатов с (skill = "C ++" и skill = "UML") и NOT (skill = "Python")
Я бы порекомендовал group by
и having
.
select j.candidate_id
from jobs j join
skills s
on j.job_id = s.job_id join
skill_names sn
on sn.skill_id = s.skill_id
group by j.candidate_id
having sum(s.skill_name = 'C++') > 0 and
sum(s.skill_name = 'UML') > 0 and
sum(s.skill_name = 'Python') = 0;
Предостережение заключается в том, что это дает навыки, прикрепленные к заданиям , а не непосредственно к кандидату. Возможно, это является требованием для вашего определения навыка, но возможно, что у вас просто нет работы для некоторых навыков для некоторых кандидатов.
Может использовать подзапрос для skill_name IN IN ('C ++', 'UML'), присоединиться к skill_name NOT IN ('Python')
select c.*
from camdidates c
inner join jobs j on c.candate_id = j.candidate_id
inner join (
select sn.skill_id, sn.job_id
from skill_name sn
inner join skill s1 on s1.skill_id = sn.skill_id
and s.skill_name IN ('C++', 'UML')
inner join skill s2 on s2.skill_id = sn.skill_id
and s2.skill_name NOT IN ('Python')
) t on t.job_id = j.job_id
Но если вы хотите «C ++» и «UML», то можете использовать 3 соединения с навыком
select c.*
from camdidates c
inner join jobs j on c.candate_id = j.candidate_id
inner join (
select sn.skill_id, sn.job_id
from skill_name sn
inner join skill s1 on s1.skill_id = sn.skill_id
and s1.skill_name = 'C++'
inner join skill s3 on s1.skill_id = sn.skill_id
and s3.skill_name = 'UML'
inner join skill s2 on s2.skill_id = sn.skill_id
and s2.skill_name <> 'Python'
) t on t.job_id = j.job_id
Может быть, что-то вроде этого (не проверено в редакторе)
select distinct c.candidate_id
from candidates c
where
exists (
select 1
from skill_names sn
join skills s
on sn.skill_id=s.skill_id
join jobs j
on s.job_id=j.job_id
and j.candidate_id=c.candidate_id
where sn.skill_name='C++'
) and
exists (
select 1
from skill_names sn
join skills s
on sn.skill_id=s.skill_id
join jobs j
on s.job_id=j.job_id
and j.candidate_id=c.candidate_id
where sn.skill_name='UML'
) and
not exists (
select 1
from skill_names sn
join skills s
on sn.skill_id=s.skill_id
join jobs j
on s.job_id=j.job_id
and j.candidate_id=c.candidate_id
where sn.skill_name='Phyton'
)
Проблема здесь в том, что навыки связаны не с кандидатом, а с работой. Таким образом, кандидат мог присоединиться к работе, но это не раскрывает его реальных навыков. Для более простой и понятной модели выполнения этого запроса навыки должны быть напрямую связаны с кандидатом.
Похожие вопросы
Связанные вопросы
Новые вопросы
mysql
MySQL - это бесплатная система управления реляционными базами данных с открытым исходным кодом (RDBMS), использующая язык структурированных запросов (SQL). НЕ ИСПОЛЬЗУЙТЕ этот тег для других БД, таких как SQL Server, SQLite и т. Д. Это разные БД, которые все используют свои собственные диалекты SQL для управления данными.