复杂的搜索问题

问题描述:

我有表款(表)在我的数据库字段名称,如复杂的搜索问题

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的标签ID为9和10,那么我想要它只会返回taggable_id(这是employmenthistories.id)谁拥有这两个tag_id(即9和10)的共同taggable_id标记表

例如我有两个用户tariq和kamal,这两个用户都有第9个标签,但kamal没有标签第10个,所以需要查询哪个如果传递这两个标签应该只返回tariq,其标签都是marahing这两个标签,但用户喜欢kamal匹配任何标签也应过滤

php chat room

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 

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

它不是我想要的东西也给我的用户在标签列表中的任何标签匹配的方式工作,但是我想,所有的标签都应该匹配,则它给我的用户,否则不是 – 2011-06-10 14:29:59

+0

@afridi,更新了查询,这是否更好? – Johan 2011-06-10 15:46:48

+0

没有人,它不工作:( – 2011-06-11 08:20:58

我已重新编写查询。

一些变化:

  • 上tags.id = taggings.tag_id
  • 删除或从whe​​re子句中加入标签,并使用,提高了性能。
 
    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没有标签名称1oth,所以它应该排除kamal并仅显示tariq – 2011-06-10 14:26:22

+0

这意味着您需要那些必须具有“第9”和“第10”标签的用户,如果这是正确的,请参阅该查询的更新版本。 – 2011-06-10 17:06:37

+0

没有亲爱的,它不会工作,也会放在两个之间标签意味着标签名称应该同时满足第9和第10个标签,这是我们不得不放在标签名称第9位和搜索标签名称第10位,然后我们将同时检查这些搜索是否在taggsable表中被标记为taggable_id的工作id是否相同 – 2011-06-11 08:17:33