【问题标题】:Somewhat complex MySql query有点复杂的 MySql 查询
【发布时间】:2019-05-02 16:25:41
【问题描述】:

下面的架构图。基本上,最底层是技能,然后是工作,然后是候选人(暂时忽略公司)。每个技能可以关联多个工作,一个工作可以有多个技能。每个职位适用于一个候选人,该候选人可以拥有(拥有)多个(历史)职位,每个职位都在一家公司。

我只是无法找出所有具有 X 技能的候选人的查询。

事实上,它变得复杂了,因为 X 不只是一个技能,它可以是多个技能,带有布尔运算符,例如

找到所有具有 (skill="C++" and 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

顺便说一句,架构来自this question 的答案,我觉得不错,但是...

【问题讨论】:

  • 但是根据图表,候选人没有技能,只有工作有技能。
  • 一些示例数据可能会有所帮助...
  • @JoakimDanielson 这正是我的难处。我认为我想找到与技能条款匹配的每个工作,然后为每个工作获取候选人并将其返回。但是,我不知道怎么做:-(
  • 如果每个技能可以关联多个工作,并且一个工作可以有多个技能,那么技能和工作之间就存在多对多的关系。但我没有看到可以建立这种关系的链接表。
  • 每个技能在skills 表中都有一个job_id - 您是从技能到工作的“上升”链接,而不是从工作到其技能的“下降”链接(我的架构错了吗? )请查看this question的答案,谢谢

标签: mysql sql


【解决方案1】:

找到所有具有 (skill="C++" and 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;

需要注意的是,这会将技能附加到工作,而不是直接应用于候选人。也许这是你对技能定义的要求,但也有可能你根本就没有为某些候选人提供某些技能的工作。

【讨论】:

  • 谢谢。除非我更改架构——这对我来说看起来不错(?)——那么它必须是那样的。找到技能,然后是使用这些技能的工作,最后是从事这些工作的候选人。顺便说一句,你会查询封面搜索在多个工作中使用的多种技能吗?例如,搜索C++ AND Pyton,其中候选人 X 具有这些技能,但具有来自工作 Y 的 CC++ 和来自工作 Z 的 Python?
  • 用户将输入一个查询。 示例 (C+ +AND UML OR Python), which I can programmatically graft on to your HAVING` 子句。所以,那应该只是找到;这通常会处理任何有效的用户输入的搜索词。正如我所问的,您上面的查询是否适用于候选人的所有工作/技能。
  • @Mawg 。 . .您可以调整having 条件来处理工作和技能。但是,这将是一个不同的问题,您应该提出一个包含样本数据和所需结果的新问题。
  • 谢谢,戈登。我会以此为起点,从那里自学。如果仍然卡住,我会问一个更好的问题,但这个答案肯定是很好的指导。
【解决方案2】:

可能正在使用一个子查询,用于技能名称 IN IN ('C++', 'UML') join to 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 join with Skill

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 

【讨论】:

  • C++ 和 UML,不是或。你的只有一个或两个都返回。我只想再添加一个内部连接来保持 C++ 和 UML 单独需要的连接
  • 对不起,我认为我的问题不够清楚(现已更新)。我不是为那个特定的“(skill="C++" and skill="UML") and NOT(skill="Python")”寻求解决方案,而是为任何包含强大技能的布尔表达式寻求解决方案
【解决方案3】:

可能是这样的(未在编辑器中测试)

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

这里的问题是技能与候选人无关,而是与工作有关。所以候选人本可以加入这份工作,但并没有透露他的真正技能。对于执行该查询的更直接和易于理解的模型,技能应该与候选人直接相关。

【讨论】:

  • 将技能与候选人而非工作联系起来的问题在于,我无法(轻松())在 Y 公司搜索具有 X 技能或在过去 Z 年内具有 X 技能的人。我认为架构是正确的(?YMMV)。实际上它是一棵树,就像你的简历/简历一样——每个候选人都有多个工作,每个工作都使用多种技能。技能可以在工作中重复。每个工作只有一个公司(和开始/结束日期)。
  • 好的,我明白了。我只是想强调一下,您的查询不会返回具有这些技能的候选人,但候选人加入了一项需要这些技能的工作(因此,候选人可能拥有使用此模型我们永远不知道的其他技能)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多