2012-11-20 74 views
1

我试图搜索所有具有所有已输入标签的用户,但它通过查找同一列来搜索它们。通过查询同一列获取具有所有输入值的所有行

SELECT u.*, t.* FROM user u 
LEFT JOIN user_tags ut ON u.id = ut.user_id 
LEFT JOIN tags t ON ut.tag_id = t.id 
WHERE t.name = tag1 AND t.name = tag2 

我按标签仅搜索和每个用户都必须全部录入的标签,而不仅仅是1.我使用PHP基于值的数量再添及条款进入,所以如果有3个值将如下所示:

SELECT u.*, t.* FROM user u 
LEFT JOIN user_tags ut ON u.id = ut.user_id 
LEFT JOIN tags t ON ut.tag_id = t.id 
WHERE t.name = tag1 AND t.name = tag2 AND t.name = tag3 

t.name只包含1个标记名称,而不是以逗号分隔的值。标签名称是通过user_tags表链接到每个用户,每个用户ID可以在多个标签ID,像这样:

user_id | tag_id 
40  | 3 
40  | 4 
41  | 1 
41  | 2 
41  | 3 

而我当前的查询返回任何内容,因为没有列具有所有3个标签名称。

+0

所以我猜t.name是一个逗号分隔的字段?必须使用'LIKE'进行字符串搜索 – wesside

+0

您可以告诉我们更多关于存储在t.name中的内容吗? – Toby

+2

您可以添加具有预期结果的样本记录吗? –

回答

1

最简单的解决办法是以下哪里是相同的'count'是您要查询的标签数量,因此您只会获得拥有所有指定标签的用户。

SELECT u.*, count(*) as `count` 
FROM `user` u 
    JOIN `user_tags` ut ON ut.`user_id`=u.`id` 
    JOIN `tags` t ON t.`id`=ut.`tag_id` 
WHERE t.`name`='tag1' OR t.`name`='tag2' 
GROUP BY u.`id` 
HAVING `count` = 2 
+0

谢谢,这正是我正在寻找的。 – user1838867

1

你可以做这样的事情。它只会返回具有全部3个标签的用户标识。

SELECT u.id 
FROM  user u 
      LEFT JOIN user_tags ut ON u.id = ut.user_id 
      LEFT JOIN tags t ON ut.tag_id = t.id 
GROUP BY u.id 
HAVING  SUM(CASE WHEN t.name = tag1 THEN 1 ELSE 0 END) > 0 
      AND SUM(CASE WHEN t.name = tag2 THEN 1 ELSE 0) > 0 
      AND SUM(CASE WHEN t.name = tag3 THEN 1 ELSE 0) > 0 
+0

很好的答案。然而,使用内部连接和一个额外的ON子句会稍快些,例如:INNER JOIN user_tags ut ON u.id = ut.user_id INNER JOIN标记t ON ut.tag_id = t.id AND t.name IN(tag1, tag2,tag3) - 在使用HAVING子句之前,这将消除没有标签1,2或3的用户。 –

+0

好点。我在想,只有3个标签。但有可能有更多。我无法真正了解这个问题。 – Tom

+0

不仅如此,但那些没有指定标签的用户呢?你想在组队之前消除它们。还请注意,我在下面添加了另一个不使用组的应用程序,这应该是非常高性能的。 –

0

允许使用GROUP_CONCAT ...

SELECT 
    u.* 
FROM 
    user u 
    JOIN user_tags ut ON ut.user_id = y.id 
    JOIN tags t ON t.id = ut.tag_id 
WHERE 
-- limit only the tags you want 
    t.name IN (tag1, tag2, ...) 
GROUP BY 
    u.id 
HAVING 
    GROUP_CONCAT(t.name ORDER BY t.name SEPARATOR ',') = 'tag1,tag2,...' 

需要注意的是,在有节,标记顺序应在条件两边

+0

让我们杀死数据库... –

相关问题