Reputation: 935
I have 2 mysql tables -
candskill - (cis, sid) - where cid = candidate id, and sid = skill id
Data in candskill (size - 257,000) -
c1, s1
c1, s2
c2, s3
c1, s4
c2, s5
...
skills - (sid, name) - where sid = skill id, and name = skill name
Data in skills (size 257,000)-
s1 - oracle
s2 - project management
s3 - oracle
s4 - testing
s5 - testing
...
Now, I want to fetch all the candidates who have skills 'oracle' and 'testing' both. Or I want candidate who have skills either 'oracle' or 'testing'. I want to have any AND/OR combination of skills present, and want to fetch candidates for those skills.
How would I achieve that?
This is what I have so far, which is not working in all scenarios.
select distinct(cs.cid), s.name from candskill cs
inner join skills s on (cs.sid = s.sid and (s.name = 'oracle' or s.name = 'testing'))
Also, the query execution is taking too much time. approx 120 sec. How do we go about doing that.
I am thinking of writing a query, and passing the skill part of the query via php code, concate the strings, and generate new query each time a user searches for candidates for a particular skill.
Upvotes: 0
Views: 63
Reputation: 74018
Maybe reducing the set of skills helps with the performance, e.g.
select cs.cid
from (select sid from skills where name in ('oracle', 'testing')) s
join candskills cs on cs.sid = s.sid
Instead of joining 250,000 x 250,000 rows, this will join 2 x 250,000 rows.
Furthermore, adding an index on skills.name
and another on skills.sid
and candskills.sid
might improve the query further.
Upvotes: 1
Reputation: 133360
You could use an having clause on count of s.name
select cs.cid
from candskill cs
inner join skills s on (cs.sid = s.sid and s.name in ( 'oracle' , 'testing'))
group by cs.cid
having count(distinct(s.name)) = 2
for 1 or 2
select cs.cid
from candskill cs
inner join skills s on (cs.sid = s.sid and s.name in ( 'oracle' , 'testing'))
group by cs.cid
having count(distinct(s.name)) >= 1
Upvotes: 1