简体   繁体   English

查询多对多关系增加了难度

[英]Querying a many-to-many relationship with added difficulty

Here is my problem: I have two tables connected trough a junction table. 这是我的问题:我有两个通过联结表连接的表。 I'm using MySQL and PHP (Yii2) on an Apache server, but its just the SQL i need help with. 我在Apache服务器上使用MySQL和PHP(Yii2),但它只是我需要帮助的SQL。

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

I need to create a query that returns objects that is tagged with several tags, and my question is if this is doable with reasonable efficiency as a publicly accessible feature as a query. 我需要创建一个查询,该查询返回带有多个标签标记的对象,而我的问题是,作为一种可公开访问的功能,该查询是否可以以合理的效率实现。

Example: find all objects with tags 'tagone', 'tagtwo' and 'tagthree'. 示例:查找所有带有标签“ tagone”,“ tagtwo”和“ tagthree”的对象。

I have one solution that works, and that is to have a 'tags'-column in the Objects-table, with all the tag-names divided by commas. 我有一个可行的解决方案,那就是在Objects-table中有一个'tags'列,所有的标签名都用逗号分开。 This does not seem like a 'best practice'-kinda solution. 这似乎不是“最佳实践”这种解决方案。

I really appreciate any help you guys can provide! 非常感谢你们能提供的任何帮助!

The SQL for this is relatively straightforward: 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')
)

The COUNT(DISTINCT t.id) joins ObjectHasTag to Tag , filters Tag on the list that you would like to search, and counts the number of distinct tags. COUNT(DISTINCT t.id)ObjectHasTag连接到Tag ,在要搜索的列表上过滤Tag ,并计算不同标签的数量。 In order for the object to be selected, all three items from the IN list must be present. 为了选择对象,必须列出IN列表中的所有三个项目。 If you know that ObjectHasTag cannot contain duplicate tagging, for example, because you have a unique index or a constraint on the table, you can replace COUNT(DISTINCT t.id) with COUNT(*) . 例如,如果您知道ObjectHasTag不能包含重复标记,因为您在表上具有唯一索引或约束,则可以将COUNT(DISTINCT t.id)替换为COUNT(*)

The o.id = ot.object_id condition "connects" the nested query to the object selected from Objects table. o.id = ot.object_id条件将嵌套查询“连接”到从“ Objects表中选择的Objects

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM