如何查询关系 table 中的相关标签?

How can I query related tags from a relationship table?

我在网站上找不到问题的答案。

我有 3 个 table:数据、标签和 data_tag_rel。

数据

id     data
------------------------------------
1      A string of long data A.
2      A string of long data B.
3      A string of long data C.
4      A string of long data D.
5      A string of long data E.
6      A string of long data F.
7      A string of long data G.
8      A string of long data H.
n      Etc...

标签

id     tag
------------
1      gold
2      silver
3      copper
4      emerald
5      steel
6      ruby
7      carbon
8      zinc
9      mercury
n      Etc...

data_tag_rel

data     tag
------------------
1        1
1        2
2        1
3        2
4        3
5        1
5        2
5        3
6        1
7        1
8        1
8        2
8        4
8        6
n        n

如你所见,有数据和标签,还有一个关系table来确定什么标签分配给什么数据。这里的数据是在谈论矿物和岩石。

我要的查询是SELECT关系table中一组更多标签相关的标签(id和name) ,通过查看它们共同针对的数据 ID。

例如,假设我分配了一个数据 ID 8 与标签 1:"gold"、2:"silver"、4:""ruby" 和 6:"emerald" 相关关系 table。所以现在我想查询常用标签。如果我查询“金”、“银”,我希望返回:

一个。 “gold”、“silver”、“ruby”和“emerald”(包括搜索标签)。 要么 B. "ruby" 和 "emerald"(不包括搜索标签)。

目的是点击一个标签,看看还有哪些其他标签与该点击标签相关,通过它们共同关联的数据,使用关系 table 作为指导。

到目前为止,我设法让它只搜索 1 个标签,但我无法让它搜索 2、3 或 n 个标签。

SELECT DISTINCT tags.tag FROM tags, data_tag_rel WHERE tags.id = data_tag_rel.tag AND data_tag_rel.data IN (SELECT data_tag_rel.data FROM data_tag_rel WHERE data_tag_rel.tag IN (SELECT tags.id FROM tags WHERE tags.tag IN ('gold')));

如何将相关标签查询到此数据库结构中的 2 个或更多标签列表?

非常感谢!

我觉得你想要的逻辑是:

select t.*
from tags t
where exists (
    select 1
    from data_tag_rel dtr
    inner join data_tag_rel dtr1 on dtr1.data = dtr.data
    inner join tags t1 on t1.id = dtr1.tag
    where t1.tag in ('gold', 'silver') and dtr.tag = t.id
)
SELECT
  data_tag_rel.data
FROM
  data_tag_rel
WHERE
  data_tag_rel.tag IN ((SELECT id FROM tags WHERE tags.tag IN ('silver', 'gold')))
GROUP BY
  data_tag_rel.data
HAVING
  COUNT(*) = 2

如果一个数据项可能多次具有相同的标签,那会略有变化...

HAVING
  COUNT(DISTINCT data_tag_rel.tag) = 2

讨厌的嵌套IN()如果喜欢也可以换...

FROM
  data_tag_rel
INNER JOIN
  tags
    ON tags.id = data_tag_rel.tag
WHERE
  tags.tag IN ('silver', 'gold')

症结在于;正常过滤,然后使用 HAVING 子句来确保您有两个数学,而不仅仅是一个。

编辑:

要明确说明如何从那里到达相关标签,只需重新加入 data_tag_rel table...

SELECT DISTINCT
  tags.tag
FROM
(
  SELECT
    data_tag_rel.data  AS id
  FROM
    data_tag_rel
  WHERE
    data_tag_rel.tag IN ((SELECT id FROM tags WHERE tags.tag IN ('silver', 'gold')))
  GROUP BY
    data_tag_rel.data
  HAVING
    COUNT(*) = 2
)
  AS data
INNER JOIN
  data_tag_rel
    ON data_tag_rel.data = data.id
INNER JOIN
  tags
    ON tags.id = data_tag_rel.tag