MySQL选择与另一个实体

时间:2016-01-25 19:37:06

标签: mysql sql join

我有以下表结构:

tags            image_tags          image
------------    ----------------    ---------------
id  tag         tag_id  image_id    id    etc...
------------    ----------------    ---------------
1   apple       1       1           1   image_1.jpg
2   banana      2       1           2   image_2.jpg
3   cherry      2       2
                3       2

标签通过多对多关系连接到图像。

我想获得至少在一张图片中一起显示的标签列表。类似的东西:

-----------------
a        b
-----------------
apple    banana
banana   cherry

etc..

每个标签对应该只出现一次,并且对的顺序并不重要。我们将使用此数据为网络图创建.dot文件。

我不确定如何构建这样的查询。

1 个答案:

答案 0 :(得分:1)

如果我们每次只有2列,那么需要一个自连接和2个连接到标签。但是,这将消除图像只有1个标记的所有记录。如果你需要那些我们需要改变一些连接。

这将占每个图像的n个记录,每个只有1个配对。例如。 Apple,Cherry而不是Cherry Apple。这是通过匹配IT.Tag_ID < IT2.Tag_ID

来完成的
SELECT Distinct T.tag A, T2.Tag B
FROM image_tags IT
INNER JOIN tags T
 on T.ID = IT.Tag_Id
INNER JOIN Image_tags IT2
 on IT2.image_ID = IT.Image_ID
and IT.Tag_ID < IT2.Tag_ID
INNER JOIN Tags T2
  on IT2.tag_ID = T2.Tag_ID

根据您的数据,这将为您提供。

-----------------
a        b
-----------------
apple    banana
banana   cherry

但是,如果您在标签3的图像1中添加了标签,那么您将获得

-----------------
a        b
-----------------
apple    banana
banana   cherry
apple    cherry

这是因为2的3种组合是3.香蕉樱桃由于图像2而被列出两次但是明显消除了重复。 &lt;使它成为一种组合,好像我们没有使用任何东西,我们最终会置换。 (Apple Banana)会被认为不同于(Banana Apple)根据您的输出我相信您是在组合之后。

---------------------------------- OLD RESPONSE _----------- ---

我不再相信你正在寻找在mySQL中找到的聚合函数group_concat()

这允许您将多行合并为一行。

Select group_Concat(T.tag ORDER BY t.tag SEPARATOR ',') as All_Image_Tags
FROM image_tags IT
INNER JOIN tags T
 on T.ID = IT.Tag_Id
GROUP BY IT.image_ID

也许你刚好在配对之后......

Select concat(A.Tags, ',', B.tags)
FROM tags a
cross join tags B
Where A.Tag < B.Tag