Mysql连接匹配每个表的多行

时间:2012-07-05 01:58:17

标签: mysql sql

以下是我的数据库相关部分的简化版本:

Person:
    id

PersonSkills:
    person_id
    skillname
    ability

Position:
    id

PositionSkills:
    position_id
    skillname
    ability

一个人可以拥有任意数量的PersonSkills,假设在这个例子中,我们的用户有6个。 一个位置可以要求任意数量的PositionSkills,假设在这种情况下该位置需要3。 我需要一个查询来确定与此职位相关联的所有PositionSkills是否都存在于与此人相关联的PersonSkills中。 (我还需要确保PersonSkill的能力大于PositionSkill的能力,但我认为一旦我弄清楚在这里给我带来麻烦的部分,这将很简单。)

提前致谢, 杰森

修改

以下是我正在寻找的更多细节:

PersonSkills
+-------------+---------+---------+
| person_id   | skill   | ability |
+-------------+---------+---------+
|     1       |  A      | 5       |
|     1       |  B      | 4       |
|     1       |  C      | 5       |
|     1       |  D      | 4       |
|     1       |  E      | 5       |
+-------------+---------+---------+

PositionSkills
+-------------+---------+---------+
| position_id | skill   | ability |
+-------------+---------+---------+
|     5       |  A      | 3       |
|     5       |  B      | 3       |
|     5       |  C      | 3       |
|     6       |  A      | 3       |
|     6       |  B      | 3       |
|     6       |  Z      | 3       |
+-------------+---------+---------+

由于我是用户1,我想要一个查询告诉我,我有资格获得职位5,因为我有技能A,B和C,它需要,但我不符合位置6,因为我缺乏技能Z

再次感谢, 杰森

1 个答案:

答案 0 :(得分:2)

试试这个解决方案:

SELECT
    a.id,
    (COUNT(c.position_id) = (SELECT COUNT(*) FROM positionskills WHERE position_id = <position_id here>)) AS isQualified
FROM
    person a
LEFT JOIN
    personskills b ON a.id = b.person_id
LEFT JOIN
    positionskills c ON 
        b.skillname = c.skillname AND 
        b.ability >= c.ability AND
        c.position_id = <position_id here>
GROUP BY
    a.id
WHERE
    a.id = <person_id here>

如果此人符合条件,则isQualified将为1,否则将为0

编辑:根据问题的澄清,要获得此人有资格获得的所有职位,请使用此解决方案:

SELECT
    a.position_id
FROM
    (
        SELECT bb.position_id, COUNT(*) AS skillshave
        FROM personskills aa
        INNER JOIN positionskills bb ON aa.skillname = bb.skillname AND aa.ability >= bb.ability
        WHERE aa.person_id = <person_id here>
        GROUP BY bb.position_id
    ) a
INNER JOIN
    (
        SELECT position_id, COUNT(*) AS skillsrequired
        FROM positionskills
        GROUP BY position_id
    ) b ON a.position_id = b.position_id AND a.skillshave = b.skillsrequired