我有桌子:
CandidatesCandidateLanguagesCandidateSkills每位候选人可能拥有1种以上的语言和1种以上的技能
所以对于Candidate"FRED",他的记录CandidateLanguages可能是
FRED - ENGLISH
FRED - FRENCH
Run Code Online (Sandbox Code Playgroud)
他的记录CandidateSkills可能是
FRED - RUNNING
FRED - JUMPING
Run Code Online (Sandbox Code Playgroud)
而对于Candidate"JIM"他的记录CandidateLanguages可能是
JIM - ENGLISH
Run Code Online (Sandbox Code Playgroud)
他的记录CandidateSkills可能是
JIM - RUNNING
Run Code Online (Sandbox Code Playgroud)
我的查询需要选择符合多种技能和语言的候选人.
例如,用英语:
选择所有所选语言的所有候选人,并拥有所有选定的技能......
或换一种方式....
SELECT ALL candidates WHERE
(language = 'FRENCH' AND language is 'ENGLISH') AND
(skill = 'RUNNING' AND skill = 'JUMPING')
Run Code Online (Sandbox Code Playgroud)
在上面两个候选人中,这应该只返回"FRED"
我知道问题是尝试从语言和技能表中选择多个记录,我认为可能需要连接,但现在我迷路了......
您正在解决的问题称为关系划分。
请参阅这篇文章:Divided We Stand: The SQL of Relational Division和这个问题,了解解决它的几种方法:How to filter SQL results in a has-many-through relation
解决这个问题的一种方法(通常来说,这是最有效的):
SELECT ALL c.candidate
FROM Candidates c
JOIN CandidateLanguages lang1
ON lang1.candidate = c.candidate
AND lang1.language = 'English'
JOIN CandidateLanguages lang2
ON lang2.candidate = c.candidate
AND lang2.language = 'French'
JOIN CandidateSkills sk1
ON sk1.candidate = candidate
AND sk1.skill = 'Running'
JOIN CandidateSkills sk2
ON sk2.candidate = candidate
AND sk2.skill = 'Jumping' ;
Run Code Online (Sandbox Code Playgroud)
另一种方法似乎更容易编写,特别是在涉及很多语言和技能的情况下,是使用两个派生表,GROUP BY每个表中包含:
SELECT ALL c.candidate
FROM Candidates c
JOIN
( SELECT candidate
FROM CandidateLanguages
WHERE language IN ('English', 'French')
GROUP BY candidate
HAVING COUNT(*) = 2 -- the number of languages
) AS lang
ON lang.candidate = c.candidate
JOIN
( SELECT candidate
FROM CandidateSkills
WHERE skill IN ('Running', 'Jumping')
GROUP BY candidate
HAVING COUNT(*) = 2 -- the number of skills
) AS sk
ON sk.candidate = c.candidate ;
Run Code Online (Sandbox Code Playgroud)