2011-06-10 2 views
0

나는 테이블 내 데이터베이스 모델 (테이블)가 이름 복잡한 검색 문제

tags     (id, name) 
taggings    (id, tag_id, taggable_id, taggable_type, context) 
employment_histories (id, user_id, grades, subjects, my_interests) 
users    (id) 

taggable_id

처럼 실제로 employment_histories_id입니다 필드와 상황에 맞는 학년 또는 과목 또는 my_interests 지금

이 될 수 있습니다 예 : 태그 배열 g = { "9th", "10th"} 사용자를 얻고 싶습니다. 태그는 모두 위의 g 배열과 일치합니다. 나는 아래의 쿼리 작성했습니다

:

SELECT DISTINCT users.* FROM `users` 
LEFT OUTER JOIN `employment_histories` 
    ON `employment_histories`.`user_id` = `users`.`id` 
LEFT OUTER JOIN `taggings` 
    ON `employment_histories`.`id` = `taggings`.`taggable_id` 
    AND `taggings`.`taggable_type` = 'EmploymentHistory' 
LEFT OUTER JOIN `tags` ON taggings.context = 'subjects' 
WHERE tags.name='9th' OR tags.name='10th' 

을하지만, 나에게 태그의 일치 너무하는 사용자를 제공하지만 나는 모든이 태그를 일치 해당 사용자가 반환 할

태그 9 번과 10 번에 9 번 태그와 10 번 태그가 있다고 가정하면이 tag_id (9와 10)에 공통 taggable_id가있는 taggable_id (즉 employhistories.id) 만 반환됩니다. 태깅 테이블

예를 들어 나는 두 사용자 tariq와 kamal이 두 사용자는 공통적으로 9 번째 태그를 가지고 있지만 kamal은 10 번째 태그를 가지므로이 두 태그는 tariq 만 반환해야합니다.이 태그는 모두이 두 태그를 처리하지만 kamal은 태그도 필터링해야합니다.

답변

2

:

SELECT 
users.* , 
count(*) AS count 
FROM users 
    LEFT JOIN employment_histories ON users.id = employment_histories.user_id 
    LEFT JOIN tagging ON tagging.taggable_id = employment_histories.id 
    LEFT JOIN tags ON tags.id = tagging.tag_id 
WHERE tags.name = "9th" 
     OR tags.name = "10th" 
GROUP BY users.id 
HAVING count = 2 
2
SELECT users.* FROM users 
INNER JOIN employment_histories 
    ON employment_histories.user_id = users.id 
INNER JOIN taggings 
    ON employment_histories.id = taggings.taggable_id 
    AND taggings.taggable_type = 'EmploymentHistory' 
    AND taggings.context = 'subjects' 
INNER JOIN tags ON tags.id = taggings.tag_id 
WHERE tags.name IN ('9th','10th') 
GROUP BY users.id 
HAVING COUNT(DISTINCT(tags.name)) = 2; 
+0

는 또한 태그 목록의 태그와 일치하는 나에게 사용자를주는 무슨 내가 그것을 원하는 방식으로 작업하지만 난 모든 태그는 다음과 일치해야하지 그렇지 않으면 사용자에게 그렇지 않다. –

+0

@afridi, 쿼리가 업데이트되었는데, 더 잘 작동합니까? – Johan

+0

아무 남자도 그 일을하지 않습니다 : ( –

1

나는이 질문을 다시 작성했습니다.

몇 가지 변경 :

  • 가입 절 tags.id = taggings.tag_id
  • 제거에 OR 곳에서 태그 및 사용은 성능을 향상시킵니다. php chat room에서
 
    SELECT DISTINCT users.*, count(*) as totRow FROM `users` 
    LEFT OUTER JOIN `employment_histories` 
    ON `employment_histories`.`user_id` = 
    `users`.`id` LEFT OUTER JOIN 
    `taggings` ON 
    `employment_histories`.`id` = 
    `taggings`.`taggable_id` AND 
    `taggings`.`taggable_type` = 
    'EmploymentHistory' AND 
    `taggings`.`context` = 'subjects' 
    LEFT OUTER JOIN `tags` ON `tags`.`id` = `taggings`.`tag_id` 
    WHERE tags.name = '9th' or tags.name = '10th' 
    GROUP BY `users`.`id` 
+0

미안해 나도 원하는 일을 내게주고 싶지 않아. 나는 두 명의 사용자가 tariq와 kamal 있고 둘 다 9 번째 태그 공통점이 있지만 kamal doesnt는 태그 이름이 1oth이므로 exlude해야합니다. kamal 및 display only tariq –

+0

태그가 "9th"및 "10th"이어야하는 사용자가 필요하다는 것을 의미합니다. 정확하다면 업데이트 된 버전의 쿼리를 참조하십시오. –

+0

작동하지 않을 것입니다. 태그는 태그 이름이 9 번째와 10 번째를 모두 충족해야한다는 것을 의미합니다. 태그 이름 9 번째 검색 및 태그 이름 10 번째 검색과 같아야하며 태그보다 위에 올려 놓아야합니다. 이러한 검색은 취업 ID가 동일한 지 여부가 taggable_id로 알려진 taggsings 테이블에 있는지 여부를 확인합니다. –