通过增加难度来查询多对多关系

时间:2015-03-12 17:14:11

标签: mysql sql

这是我的问题: 我有两个表通过连接表连接。 我在Apache服务器上使用MySQL和PHP(Yii2),但它只是我需要帮助的SQL。

| Objects     |    ObjectHasTag    |   Tag    |
|---------------------------------------------|
| - id        |    -object_id      |   -id    |
| - name      |    -tag_id         |   -tag   |

我需要创建一个返回被多个标签标记的对象的查询,我的问题是,这是否可以合理有效地作为查询的公共可访问功能。

示例:找到所有带标签的对象' tagone',' tagtwo'和' tagthree'。

我有一个有效的解决方案,那就是在Objects-table中有一个'标签' -column,所有的标签名称都用逗号分隔。这似乎不是最佳实践' -kinda解决方案。

我非常感谢你们提供的任何帮助!

1 个答案:

答案 0 :(得分:1)

SQL的相对简单:

SELECT *
FROM Objects o
WHERE 3 = (
    SELECT COUNT(DISTINCT t.id)
    FROM ObjectHasTag ot
    JOIN Tag t ON t.id=ot.tag_id
    WHERE o.id = ot.object_id
      AND t.tag IN ('tag1', 'tag2', 'tag3')
)

COUNT(DISTINCT t.id)ObjectHasTag加入Tag,过滤您要搜索的列表中的Tag,并计算不同标记的数量。为了选择对象,必须存在IN列表中的所有三个项目。如果您知道ObjectHasTag不能包含重复标记,例如,因为您在表格上有唯一索引或约束,则可以将COUNT(DISTINCT t.id)替换为COUNT(*)

o.id = ot.object_id条件"连接"对从Objects表中选择的对象的嵌套查询。