2012-05-15 2 views
0

내가 예를 들어 두 개의 테이블필터와

사용자

---------------------------------- 
id | name | blah 
---------------------------------- 
1 | Samy | stackoverflow 
2 | jhon | some thing 
---------------------------------- 

기술

--------------------------------------- 
id | user_id | skill_title | level 
--------------------------------------- 
1 | 1  | php   | good 
2 | 1  | css   | excellent 
3 | 1  | photoshop | fair 
4 | 2  | php   | good 
--------------------------------------- 

이 있고 난이

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') 
같은 쿼리를 실행

여기서 $ skill_title은 ar입니다. ray 내가 필요로하는 모든 기술 즉 PHP, CSS 을 가진 사용자를 선택하는 것입니다. 모든 배열 요소에 대한 모든 단일 레코드를 비교하기 때문에 데이터를 가져 오지 않을 것입니다. 하지만 모든 기술을 가진 사용자를 데려 올 수 없습니다

아이디어가 있습니까?

+0

한 번에 몇 가지 기술을 검색 할 예정입니까? –

+0

변수가 10보다 크거나 작음 –

답변

1

@ joeshmo의 답변은 아마도 가장 좋은 해결책 일 수 있습니다.하지만이 시도를해볼 가치가 있습니다. 당신이 사용자의 톤이있는 경우는 빠를 수 있지만 당신이 찾고있는 기술이 바로 그 몇 :

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]') 
    ... 

그리고 당신의 PHP 스크립트는 다음과 같습니다

$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) : ""); 


또 다른 가능한 해결책은 @joeshmo가 제안한대로 복수 INNER JOIN을 사용하는 것입니다. 내가보기 위해 두 솔루션을 시도 할 것

$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); 

:

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]' 
    ... 

것은 그래서 PHP 스크립트는 다음과 같이 보일 수 있습니다 :이 작업을 수행하여 조금 작고 청소기 만들 수 있습니다 어느 것이 당신의 데이터 세트에 대해 더 잘 수행됩니다.

+0

이 작동하지만 괜찮습니다. 이 문제를 해결하기위한 정규화가 있습니까? –

+0

@SamyMassoud : 업데이트 된 답변보기. 또한 테이블에 적절한 인덱스가 있는지 확인하는 것이 좋습니다. 적어도,'users' 테이블에는'PRIMARY KEY (id)'가,'skills' 테이블에는'FOREIGN KEY (user_id) REFERENCES users (id)'가 필요합니다. – Travesty3

0

당신이 찾고있는 각 스킬에 대해 다시 참여하고 싶습니다.

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) 

쿼리의 문제점은 기술 테이블에 한 번만 참여한다는 것입니다. 검색어는 다음과 같이 작동합니다.

----------------------------------------------------- 
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 
----------------------------------------------------- 

행에 CSS와 PHP가 모두 없습니다. 내 쿼리는 다음과 같이 작동

---------------------------------------------------------------------------------------------------------------- 
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      
---------------------------------------------------------------------------------------------------------------- 

두 번째 행은 phpcss 모두 있습니다. 그것이 일치 할 것입니다.

최대 10 가지 기술에 지루한 작업입니다. 대신 여러 쿼리를 수행 할 수 있습니다.

+0

$ skill_title은 정적이 아닙니다. 필요한 모든 기술을 가진 사용자를 얻는 것이 필요합니다. 예를 들어 (CSS, PHP, MySQL 등) 스킬이 필요합니다. –

+0

잘 모르겠습니다. "$ skill_title은 정적이 아닙니다."라는 의미는 나에게이 쿼리가 * 모든 * 필요한 기술을 가진 사용자 만 얻는 것처럼 보입니다. – Travesty3

+0

@joeshmo : JOIN 조건에서 WHERE 절에 조건을 직접 넣을 수 없습니까? 'INNER JOIN 스킬'과 마찬가지로 first_skill ON users.id = first_skill.user_id와 first_skill.skill_title = '$ skill_title [0]' ' – Travesty3

0
$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); 
+0

[implode] (http://php.net/manual/en/function.implode.php) 함수를 올바르게 사용하고 있다고 생각하지 않습니다. 하나의 매개 변수와 함께 사용하는 경우에는 배열이어야하며 * glue *가 없습니다. 두 개의 매개 변수를 사용하는 경우 첫 번째 매개 변수는 * glue *입니다 (예제의 경우 "\", \ ""'와 같아야 함). 두 번째 매개 변수는 배열이어야합니다. 세 가지 매개 변수 옵션은 없습니다. – Travesty3

+0

죄송합니다. 실제로 두 개의 매개 변수로 호출하고 implode는 임의의 순서로 매개 변수를 받아들입니다. –

+0

흥미 롭습니다. 그래서 이것은 기본적으로 위의 또는 버전입니다. 그러나 여러분은 그것들이 'n'과 일치하는지 확인해야합니다. 그들은 거기에 두 번 PHP를했다면 이것은 실패 할 것입니다, 맞습니까? –

관련 문제