查找带有 tag1 和 tag2 的帖子? (using a join-table) Exists / Having / subqueries...用什么?
Finding posts with tag1 AND tag2? (using a join-table) Exists / Having / subqueries... What to use?
我需要进行查询以根据多个字词进行搜索和过滤。
我有一把带武器的 table 并且都可以有多个标签。 我希望能够为用户创建一个过滤器选项,只显示武器,例如'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
中需要的 link。但是我不确定如何添加这个…
问题:
假设我想搜索 blue
和 old
的武器记录(在本例中是一把剑)我该怎么做?
我并不是说我必须使用 "EXISTS",但我想要最佳优化的方式来搜索带有由 AND
! 连接的某些标签的帖子
试试这个:
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))
)
转过来。那是从最里面的子查询中的 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;
如果你没有规范化标签会更容易。
我需要进行查询以根据多个字词进行搜索和过滤。
我有一把带武器的 table 并且都可以有多个标签。 我希望能够为用户创建一个过滤器选项,只显示武器,例如'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
中需要的 link。但是我不确定如何添加这个…
问题:
假设我想搜索 blue
和 old
的武器记录(在本例中是一把剑)我该怎么做?
我并不是说我必须使用 "EXISTS",但我想要最佳优化的方式来搜索带有由 AND
! 连接的某些标签的帖子
试试这个:
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))
)
转过来。那是从最里面的子查询中的 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;
如果你没有规范化标签会更容易。