Схема ниже. По сути, в нижней части находятся навыки, затем рабочие места, а затем кандидаты (пока игнорируйте компании). Каждый навык может быть связан с несколькими заданиями, а задание может иметь несколько умений. Каждая работа относится к одному кандидату, который может иметь (имел) несколько (исторических) вакансий, каждая с одной компанией.

Я просто не могу понять запросы, чтобы найти всех кандидатов с навыком 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

Кстати, схема появилась из ответа на этот вопрос выглядит хорошо для меня, но ...

enter image description here

1
Mawg says reinstate Monica 1 Май 2019 в 21:42

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;

Предостережение заключается в том, что это дает навыки, прикрепленные к заданиям , а не непосредственно к кандидату. Возможно, это является требованием для вашего определения навыка, но возможно, что у вас просто нет работы для некоторых навыков для некоторых кандидатов.

1
Gordon Linoff 1 Май 2019 в 20:34

Может использовать подзапрос для 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 
0
scaisEdge 1 Май 2019 в 19:01

Может быть, что-то вроде этого (не проверено в редакторе)

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'
    )

Проблема здесь в том, что навыки связаны не с кандидатом, а с работой. Таким образом, кандидат мог присоединиться к работе, но это не раскрывает его реальных навыков. Для более простой и понятной модели выполнения этого запроса навыки должны быть напрямую связаны с кандидатом.

0
Jaime Drq 1 Май 2019 в 19:15