複数に参加使用される最も柔軟な方法で
select `t`.*, GROUP_CONCAT(DISTINCT(s.name)) as skills,
GROUP_CONCAT(DISTINCT(s.id)) as skill_ids
FROM `candidates` `t`
LEFT JOIN `candidate-skills` `cs` ON `t`.`id` = `cs`.`can_id`
LEFT JOIN `skills` `s` ON `cs`.`skill_id` = `s`.`id`
GROUP BY `t`.`id`
having find_in_set ('8', skill_ids) and find_in_set ('10', skill_ids)
ORDER BY `t`.`id` desc
。 GROUP_CONCATとコンマで区切られたリストは反パターンとみなされ、連結が正確な順序で正確に行われていないと機能しない可能性があります(スキルセット1,2,5は1,5,2と同じではないとみなされます)。
SELECT c.* FROM candidates AS c
JOIN candidateskills AS cs ON (cs.cand_id = c.id)
JOIN skills AS sk1 ON (cs.skill_id = sk1.id)
JOIN skills AS sk2 ON (cs.skill_id = sk2.id)
...other sk(N)...
WHERE (sk1.skill = 'waterskiing')
AND (sk2.skill = 'snowboarding')
...
;
例えば、各スキルは、スキルレベルがあり、このような柔軟性レベル5で以上の熟練するスノーボードのために必要がある場合、これはスキルの容易な調整を可能にするには、GROUP_CONCAT
を行うには地獄です。
しかし、単純なマッチングのために、あなたが望むスキルを選択し、ちょうどそれらをカウントすることにより、より速くそれを行うことができます。
SELECT c.* FROM candidates AS c
JOIN candidateskills AS cs ON (cs.cand_id = c.id)
WHERE cs.skill_id IN (1, 7, 24, 19, 115)
GROUP BY c.id
HAVING COUNT(1) = 5;
(より適切なSQLでは、あなたがCの明示的にすべてのフィールドを示す代わりにする必要があるだろう"c。*"をGROUP BY句で繰り返します。より巧妙なRDBMSサーバは、cのプライマリキーでグループ化する限り、気にしません。現在は、とにかく気にしませんが、厳密なモードではそうです)。
スキルごとに、スキルについてIDを取得し、上記のクエリを組み立てるためのスキルについて1つの高速クエリを実行します。
それとも、限り、あなたはスキルと完全に一致していて、単一の、より大きなクエリで行うことができます:あなたはPHPでこれをしたいので
SELECT c.* FROM candidates AS c
JOIN candidateskills AS cs ON (cs.cand_id = c.id)
JOIN skills AS s ON (cs.skill_id = s.id)
WHERE s.skill IN ('javascript', 'html5', 'php')
GROUP BY c.id
HAVING COUNT(1) = 3;
を:それは良いです
$skills = array('javascript', 'html5', 'php');
$skno = count($skills);
$set = implode(',', array_fill('?', $skno));
$params = $skills;
$params[] = $skno;
$query = "SELECT c.* FROM candidates AS c
JOIN candidateskills AS cs ON (cs.cand_id = c.id)
JOIN skills AS s ON (cs.skill_id = s.id)
WHERE s.skill IN ({$set})
GROUP BY c.id
HAVING COUNT(1) = ?";
$stmt = $db->prepare($query);
$stmt->execute($params);
while ($candidate = $stmt->fetch(PDO::FETCH_ASSOC)) {
...
}
解決策はありますが、依然として問題があります。スキルIDは5,6,7,8であり、私たちが望むのは5と7です。この状態ではこの解決法は機能しません。 –
あなたはwhere条件を分割し、それぞれのskill_idに対してandと結合することができます。 –