我需要进行查询以搜索和过滤多个字词。
我有一张带武器的桌子,所有人都可以有多个标签。 我希望能够为用户创建一个过滤器选项,只显示例如武器'tag1'和'tag2'。
直到现在:
我使用GROUP_CONCAT
和HAVING
过滤它们直到现在,但这有性能问题!因为我被迫做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
中您需要的链接。但我不确定如何添加这个......
问题:
假设我想搜索blue
和old
的武器记录,(在这种情况下是一把剑)我该怎么做?
我不是说我必须使用“EXISTS”,但我希望找到最优化的方式来搜索由AND
连接的某些标签的帖子!
答案 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
两次。我使用IN
和HAVING
来避免这种情况。
更多强>
是的,这有点棘手......
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;
如果你没有标准化标签会更容易。