查找tag1和tag2的帖子? (使用连接表)存在/拥有/子查询...使用什么?

时间:2016-03-27 10:08:18

标签: mysql left-join exists

我需要进行查询以搜索和过滤多个字词。

我有一张带武器的桌子,所有人都可以有多个标签。 我希望能够为用户创建一个过滤器选项,只显示例如武器'tag1'和'tag2'。

直到现在:
我使用GROUP_CONCATHAVING过滤它们直到现在,但这有性能问题!因为我被迫做GROUP BY w.id但我想做ORDER BY其他事情。并且GROUP BY与ORDER BY没有很好的配合......

我尝试使用EXISTS(SELECT ...)创建一些能够过滤多个值的东西,但是当中间有一个“join-table”时我不确定这样做...(所以剩下2个联接)

weapons:
id | name
----------
1  | sword
2  | shield

weapon_tag_links:
tag_id  | weapon_id
-------------------
62      | 1
80      | 1
80      | 2
60      | 2

weapon_tags:
tag_id | tag
--------------
60      | red
62      | blue
80      | old

搜索查询:

SELECT DISTINCT * FROM weapons as w
LEFT JOIN weapon_tag_links AS l ON l.weapon_id = w.id 
INNER JOIN weapon_tags AS t ON l.tag_id = t.tag_id 
WHERE EXISTS (
    ****** Something to go here *******
    WHERE t.tag = ‘blue’
) AND EXISTS (
    ****** Something to go here *******
    WHERE t.tag = ‘old’
)

我只是错过了EXISTS中您需要的链接。但我不确定如何添加这个......

问题:
假设我想搜索blueold的武器记录,(在这种情况下是一把剑)我该怎么做?

我不是说我必须使用“EXISTS”,但我希望找到最优化的方式来搜索由AND连接的某些标签的帖子!

2 个答案:

答案 0 :(得分:0)

试试这个:

SELECT * FROM wp_posts AS p
LEFT JOIN wp_term_relationships AS tr ON p.ID = tr.object_id 
LEFT JOIN wp_terms AS t ON tr.term_taxonomy_id = t.term_id 
WHERE p.id IN 
(
    SELECT p2.id FROM wp_posts AS p2
    LEFT JOIN wp_term_relationships AS tr2 ON p2.ID = tr2.object_id 
    LEFT JOIN wp_terms AS t2 ON tr2.term_taxonomy_id = t2.term_id 
    GROUP BY p2.id
    HAVING FIND_IN_SET('blue', GROUP_CONCAT(t2.term)) AND FIND_IN_SET('old', GROUP_CONCAT(t2.term))
)

答案 1 :(得分:0)

转过身来。这是从最里面的子查询中的tag IN ('blue', 'old')开始的。从那里,找到tag_ids。从他们那里,找到weapon_ids HAVING COUNT(*) = 2。最后,在最外面的查询中,获取weapon.name

EXISTS()。否LEFT JOINs;我不确定你首先需要LEFT

原始尝试需要使用不同的别名加入tag两次。我使用INHAVING来避免这种情况。

更多

是的,这有点棘手......

SELECT
     FROM  
      ( SELECT  weapon_id
            FROM  weapon_tags
            JOIN  weapon_tag_links USING(tag_id)
            WHERE  tag IN ('blue', 'old')
            GROUP BY  weapon_id
            HAVING  COUNT(*) >= 2 
      ) a
    JOIN  weapons w ON w.id = a.weapon_id;

如果你没有标准化标签会更容易。