I'm kind of new to MYSQL, this query works but wonder if there's a more efficient way. I have 2 tables... client_table and client_skills . Both tables have a 'client_id' column. I'm trying to select only the clients that match all of the requested skill code and types
This is what I first tried... (doesn't work unless you change AND to OR)
SELECT * FROM client_table
LEFT JOIN client_skills ON client_table.client_id = client_skills.client_id
WHERE (skill_code='97' AND skill_type='0')
AND (skill_code='65' AND skill_type='0')
AND (skill_code='23' AND skill_type='5')
Then I tried this... (which works and returns the results I want it to)
SELECT * FROM client_table
WHERE client_id IN
(SELECT client_id FROM client_skills WHERE (skill_code='97' AND skill_type='0'))
AND client_id IN
(SELECT client_id FROM client_skills WHERE (skill_code='65' AND skill_type='0'))
AND client_id IN
(SELECT client_id FROM client_skills WHERE (skill_code='23' AND skill_type='5'))
But if there is a shorter or more efficient way to do that I'd love to learn it. Thanks for your help
the second one is slower than the first one since you are doing 4 queries, so between those two example just go with the first one with OR instead of AND.
There may be better/faster queries, but that depends on the requirements and your table's indexes
For example, do you really need skill_type? can you have two skills with the same code and different type? if all skill codes are different, just do:
SELECT * FROM client_table
LEFT JOIN client_skills ON client_table.client_id = client_skills.client_id
WHERE skill_code IN ('97','65','23')
if you have an index on skill_code then the query would be faster too
EDIT: ok, now I understand your question, you need at least 2 queries, one to get all client ids that matches the tree skills and one to get clients with those ids, try this:
SELECT * from client_table WHERE client_id IN (
SELECT client_id FROM client_skills WHERE (skill_code='97' AND skill_type='0') OR
(skill_code='65' AND skill_type='0') OR (skill_code='23' AND skill_type='5')
GROUP BY client_id HAVING count(*) = 3)
what you are doing there is:
I think that's be fastest approach, only 2 queries, I don't think it can be done with just one query
NOTE: that query is not tested, it's the idea, you may need to play a little with HAVING and GROUP_BY
your 1st query modified using OR
is not bad. and you can do with UNION
:
SELECT client_id FROM client_skills WHERE (skill_code='97' AND skill_type='0')
UNION
SELECT client_id FROM client_skills WHERE (skill_code='65' AND skill_type='0')
UNION
SELECT client_id FROM client_skills WHERE (skill_code='23' AND skill_type='5')
you can accomplish something like this. SELF JOIN
is required. (not tested on you data):
SELECT t1.client_id
FROM client_skills t1 JOIN client_skills t2 ON t1.client_id = t2.client_id
AND t1.skill_code='97' AND t1.skill_type='0'
AND t2.skil_code='65' AND t2.skill_type='0'
JOIN client_skills t3 ON t3.client_id = t1.client_id
AND t3.skil_code='23' AND t3.skill_type='5'
is this what you're asking for since you wanted to use AND
instead of OR
sqlFiddle example in my example only has all 3 skills (of that skill_code and skill_type) 拥有全部3种技能(该skill_code和skill_type)
SELECT c.*
FROM client_table c,
client_skills s1,
client_skills s2,
client_skills s3
WHERE
c.client_id = s1.client_id AND s1.skill_code=97 AND s1.skill_type=0
AND c.client_id = s2.client_id AND s2.skill_code=65 AND s2.skill_type=0
AND c.client_id = s3.client_id AND s3.skill_code=23 AND s3.skill_type=5
It's the same logic as your second query.
SELECT
client_table.*
,SUM(
IF( skill_code='97' AND skill_type='0' ,1 ,0 )
+
IF( skill_code='65' AND skill_type='0' ,1 ,0 )
+
IF( skill_code='23' AND skill_type='5' ,1 ,0 )
) AS skill_code_type_count
FROM
client_table
LEFT JOIN client_skills ON client_table.client_id = client_skills.client_id
GROUP BY
client_table.client_id
HAVING
skill_code_type_count >= 3
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.