【问题标题】:MySQL: many to many relationship with multiple AND conditionMySQL:具有多个 AND 条件的多对多关系
【发布时间】:2019-02-16 18:59:51
【问题描述】:

我在我的 MySQL 数据库中有一个多对多关系,其中三个表如下所示:

TABLE 项目, TABLE 关系(仅存储项目和标签的 id), 表标签

每个项目可以有多个标签,标签也可以与多个项目相关,例如商品“鞋”可以有标签“运动”和“皮革”,而标签“运动”可以与商品“鞋”和“衬衫”相关。

我现在需要做的是选择所有具有一个或多个标签并由 AND 条件组合的项目,例如我想找到所有带有“运动”标签和“皮革”标签的物品。

是否可以仅使用一个查询来检索带有 AND 条件的请求数据,或者我是否需要构建子查询(或类似的东西)?

另一种方法是获取所有带有与 OR 组合的标签的项目,如下所示:

SELECT *
FROM item
LEFT JOIN relation
    ON item.id = item_id
    LEFT JOIN tag
    ON tag.id = tag_id
WHERE (tag = 'sport' OR tag = 'leather')
GROUP BY item.id;

然后过滤掉那些没有所有必要标签的标签,但我宁愿让数据库完成工作,而不是获取不必要的项目然后迭代。

【问题讨论】:

    标签: mysql many-to-many


    【解决方案1】:

    你需要使用 HAVING 命令, 是的,复杂性会迅速上升到子查询的水平......

    SELECT item.id,
    COUNT(*) AS cnt
    FROM item
    LEFT JOIN relation
        ON item.id = item_id
        LEFT JOIN tag
        ON tag.id = tag_id
    WHERE (tag = 'sport' OR tag = 'leather')
    GROUP BY item.id
    HAVING
     cnt >= 1
    

    ;

    【讨论】:

      【解决方案2】:

      你可以稍微改变你当前的查询以获得你想要的结果:

      SELECT i.id, i.name    -- OK to select name assuming id is the PK
      FROM item i
      LEFT JOIN relation r
          ON i.id = r.item_id
      LEFT JOIN tag t
          ON t.id = r.tag_id
      WHERE t.tag IN ('sport', 'leather')
      GROUP BY i.id
      HAVING COUNT(DISTINCT t.tag) = 2;
      

      这将返回同时具有sport 和leather 标签的所有项目。它通过按项目聚合来工作(就像您已经在做的那样),然后在 HAVING 子句中断言有两个不同的匹配标签。由于我们在WHERE 子句中只限制了这两个标签,如果聚合后HAVING 检查通过,则表明该项目是匹配的。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-03
        • 1970-01-01
        • 1970-01-01
        • 2021-11-16
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多