Reputation: 4385
i have two tables for example
users
----------------------------------
id | name | blah
----------------------------------
1 | Samy | stackoverflow
2 | jhon | some thing
----------------------------------
skills
---------------------------------------
id | user_id | skill_title | level
---------------------------------------
1 | 1 | php | good
2 | 1 | css | excellent
3 | 1 | photoshop | fair
4 | 2 | php | good
---------------------------------------
and i run query like this
SELECT * FROM users
INNER JOIN skills ON users.id = skills.user_id
WHERE ($skill_title[0] LIKE 'skills_title' AND
$skill_title[1] LIKE 'skills_title')
where $skill_title is an array what i need is to select user who have all this skills ie PHP,CSS if i did query like above it will never bring data because it compare every single record to all array element AND if i replaced and with Or it will work but it will no't bring user with all skills
any ideas ?
Upvotes: 0
Views: 1535
Reputation: 14479
@joeshmo's answer is probably your best solution, but it might be worth giving this a try as well. It might be faster if you have a ton of users, but very few that have the skill you're looking for:
SELECT * FROM users
WHERE
id IN (SELECT user_id FROM skills WHERE skill_title = '$skills[0]')
AND id IN (SELECT user_id FROM skills WHERE skill_title = '$skills[1]')
...
And your PHP script might look like this:
$skills = array("php", "css", ... ); // replace ... with the skills you are looking for
$whereClause = array();
for ($i=0, $count=count($skills); $i < $count; $i++)
$whereClause[] = "id IN (SELECT user_id FROM skills WHERE skill_title = '{$skills[$i]}')";
$query = "SELECT * FROM users". (count($whereClause) > 0 ? " WHERE ". implode(" AND ", $whereClause) : "");
INNER JOIN
s, as @joeshmo suggested. You might be able to make it a bit smaller and cleaner by doing this:
SELECT *
FROM
users u
INNER JOIN skills s1 ON u.id = s1.user_id AND s1.skill_title = '$skills[0]'
INNER JOIN skills s2 ON u.id = s2.user_id AND s2.skill_title = '$skills[1]'
...
So your PHP script might look something like this:
$skills = array("php", "css", ... );
$joins = array();
for ($i=0, $count=count($skills); $i < $count; $i++)
$joins[] = "INNER JOIN skills s{$i} ON u.id = s{$i}.user_id AND s{$i}.skill_title = '{$skills[$i]}'";
$query = "SELECT * FROM users u ". implode(" ", $joins);
I would try both solutions to see which one performs better for your data set.
Upvotes: 1
Reputation: 7204
I think you want to join it again for each skill you're searching for.
SELECT * FROM users
INNER JOIN skills as first_skill ON users.id = first_skill.user_id
INNER JOIN skills as second_skill ON users.id = second_skill.user_id
WHERE ($skill_title[0] LIKE first_skill.skill_title AND
$skill_title[1] LIKE second_skill.skill_title)
The problem with your query is that it is only joining the skills table once. Your query works like this:
-----------------------------------------------------
id | name | blah | skill_title | level
-----------------------------------------------------
1 | Samy | stackoverflow | php | good
1 | Samy | stackoverflow | css | excellent
1 | Samy | stackoverflow | photoshop | fair
2 | jhon | some thing | php | good
-----------------------------------------------------
No row has both css and php. My query works like this:
----------------------------------------------------------------------------------------------------------------
id | name | blah | first_skill.skill_title | first_skill.level | second_skill.skill_title | second_skill.level |
----------------------------------------------------------------------------------------------------------------
1 | Samy | stackoverflow | php | good | php | good |
1 | Samy | stackoverflow | php | good | css | excellent |
1 | Samy | stackoverflow | php | good | photoshop | fair |
... (there would be nine for Samy)
2 | jhon | some thing | php | good | php
----------------------------------------------------------------------------------------------------------------
The second row has both php
and css
. That's the one that would match.
This would be tedious for up to ten skills. You could do multiple queries instead.
Upvotes: 0
Reputation: 19224
$skills = Array("php","css", ..... );
$query = " select u.id, u.name from users u left join skills s on u.id=s.user_id "
." where s.skill_title in (\"".implode($skills,"\",\"")."\") "
." group by s.user_id having count(s.id) = ".count($skills);
Upvotes: 0