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 根据输入的值的数量添加另一个 AND 子句,因此如果有 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 个标签名称。

4

3 回答 3

1

最简单的解决方案如下,其中“计数”是您要查询的标签数量,因此您只会获得拥有所有指定标签的用户。

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
于 2012-11-20T14:37:11.437 回答
1

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

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 
于 2012-11-20T14:17:58.763 回答
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,...'

请注意,在有部分中,条件两侧的标记顺序应相同

于 2012-11-20T14:34:40.373 回答