使用多个IN子句查询多对多关系

时间:2021-05-02 12:15:18

标签: mysql many-to-many in-clause

我在对象 PoolTag 之间存在多对多关系。所以一个池可以有多个标签,一个标签可以属于多个池。我想要实现的是查询所有具有特定标签的池。用户可以选择搜索包含多个标签的标签类别。例如。 慈善类别包含环境动物教育。所以在这种情况下,我想过滤所有具有这些标签的池。这是我通过以下查询实现的:

SELECT p.id
FROM pools p
LEFT JOIN pool_to_pool_tags ptp ON p.id = ptp.pool_id
LEFT JOIN pool_tags pt ON ptp.pool_tag_id = pt.id
WHERE ptp.pool_tag_id IN (1,2,3)
GROUP BY s.id

其中池 ID 1、2 和 3 是上述命名标签的 ID,只要有一个标签匹配,我就希望在我的结果集中有池。

问题是现在用户应该能够过滤多个类别。例如。 慈善社区。因此,我的查询应该只返回那些池,这些池至少有一个 ID 为 1、2 或 3 的标签至少有一个 ID 为 4 或 5 的标签。

Here 是一个类似的问题,但并不完全相同,因为池不需要具有 IN 子句中列出的所有标签。所以我不能使用 HAVING COUNT(DISTINCT pt.id) = 2

所以我的问题归结为如何找到在每个给定类别中至少匹配一个标签的所有池?

SELECT p.id
FROM pools p
LEFT JOIN pool_to_pool_tags ptp ON p.id = ptp.pool_id
LEFT JOIN pool_tags pt ON ptp.pool_tag_id = pt.id
WHERE ptp.pool_tag_id IN (1,2,3,4,5)
GROUP BY s.id

通过将所有标签放入一个 IN 子句中,我将获得至少具有一个标签的所有池,但这并不能保证池具有两种类别的标签。所以我需要把它分开,并为每一类标签都有一个单独的 IN 子句:

SELECT p.id
FROM pools p
LEFT JOIN pool_to_pool_tags ptp ON p.id = ptp.pool_id
LEFT JOIN pool_tags pt ON ptp.pool_tag_id = pt.id
WHERE ptp.pool_tag_id IN (1,2,3)
OR ptp.pool_tag_id IN (4,5)
GROUP BY s.id

但这也将返回在一个类别中也只有一个标签的池。使用 HAVING COUNT(DISTINCT pt.id) = 2 也不起作用,因为一个池可能有多个类别的标签。例如。池 A 可能有标签 1、2 和 4。然后要匹配这个池,我需要使用 HAVING COUNT(DISTINCT pt.id) = 3,但我也想将池与标签 1 和 4 匹配,这些标签仅在我使用 HAVING COUNT(DISTINCT pt.id) = 2 时才匹配。使用 >= 也不起作用,因为 HAVING COUNT(DISTINCT pt.id) >= 2 也会匹配带有标签 1 和 2 的池。但由于它们都来自同一类别,因此不应匹配。

是否有一个查询可以完成我想要实现的目标?

提前致谢

达蒂斯觉醒

0 个答案:

没有答案
相关问题