mysql - 查询难度更大的多对多关系

标签 mysql sql

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

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

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

示例:查找带有标签“tagone”、“tagtwo”和“tagthree”的所有对象。

我有一个可行的解决方案,那就是在对象表中有一个“标签”列,所有标签名称都用逗号分隔。这看起来不像是“最佳实践”——有点像解决方案。

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

最佳答案

此 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 表中选择的对象。

关于mysql - 查询难度更大的多对多关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29016169/

相关文章:

使用关键字的 SQL 搜索查询

sql - 如何防止用户使用表空间中的空间?

mysql - 时区或时间冲突

mysql - UNION 子查询中的两个表

PHP:从基于 PDO 的 if 语句返回一个值

MySQL最大连接数

mysql - 如何存储嵌套位置?

php - 在带有行限制的表中搜索结果php

sql - 如何在分层查询中获取不同的元素列表?

mysql - 在 mysql 查询中排除由 "between"定义的值范围内的值