Putting comma-separated lists in a database is almost always the wrong way to go about things. You should have separate tables for skills, candidates, and whatever the skills are required for; and two more tables: one linking candidates to skills, the other linking the things skills are required for to the skills they require. You can then use these intermediate tables to measure how well a candidates skill set fulfills the set required.
This will get you a list of all candidates that have at least one of the skills required, ordered by how many of the skills they fulfill from best to worst:
SELECT vs.vacancy_id, cs.candidate_id
, COUNT(DISTINCT vs.skill_id) AS requiredSkillCount
, COUNT(DISITCT cs.skill_id) AS candidateSkillCount
FROM vacancy_skills AS vs
LEFT JOIN candidate_skills AS cs ON vs.skill_id = cs.skill_id
WHERE vs.vacancy_id = something
GROUP BY vs.vacancy_id, cs.candidate_id
ORDER BY candidateSkillCount DESC, cs.candidate_id ASC
;
- you can use a
HAVING candidateSkillCount = requiredSkillCount
clause to only get the fully qualified ones (or < to get the partially qualified ones),
- you can join to the
candidates
table to get the candidates' name,
- you can join to the
skills
table to use GROUP_CONCAT(skills.name ORDER BY skills) AS relevantSkillsList
to get a comma-separated list of the skills in the results as well (you'll need to join to it twice if you want name lists for the skills required and the skills possessed)