多对多关系,使查询不那么复杂

时间:2011-12-26 13:00:17

标签: mysql many-to-many

这只是我的标签系统中使用的表格设计的一个例子。

ARTICLES
id
content

TAGS
id
tag

TAGSTOARTICLES
articleid
tagid

@edit 最后在一些rubberducking之后我设法编写了以下查询:


只选择文章:

SELECT a.id, a.content, GROUP_CONCAT(t.tag) AS tags
FROM articles a
LEFT JOIN tagstoarticles tta ON tta.articleid = a.id
LEFT JOIN tags t ON t.id = tta.tagid
GROUP BY a.id

结果:

id  content         GROUP_CONCAT(t.tag)
1   Lorem ipsum 1   tag1,tag2
2   Lorem ipsum 2   tag1
3   Lorem ipsum 3   tag2

搜索代码:

SELECT a.id, a.content, GROUP_CONCAT(t.tag) AS tags
FROM articles a
LEFT JOIN tagstoarticles tta ON tta.articleid = a.id
LEFT JOIN tags t ON t.id = tta.tagid
WHERE a.id IN (SELECT A.id FROM tagstoarticles M, articles A, tags T
               WHERE M.tagid = T.id
               AND (T.tag IN ('tag1'))
               AND A.id = M.articleid
               GROUP BY A.id
               HAVING COUNT( A.id )=1
)
GROUP BY a.id

结果:

id  content         GROUP_CONCAT(t.tag)
1   Lorem ipsum 1   tag1,tag2
2   Lorem ipsum 2   tag1

但是用于搜索标签的查询是一团糟,任何解决这个问题的想法都比较容易吗?

1 个答案:

答案 0 :(得分:1)

“但是如何修改此查询以同时选择分配给本文的所有标签?”

SELECT tag FROM tags INNER JOIN tagstoarticles ON tags.id = tagstoarticles.tagid WHERE articleid=[your article's id]

“如果我只是想在不按标签搜索的情况下获得结果,该如何做到这一点?”

SELECT articles.id, tags.tag FROM articles INNER JOIN tagstoarticles ON tagstoarticles.articleid = articles.id INNER JOIN tags ON tagstoarticles.tagid = tags.id ORDER BY articles.id, articles.date

这为每个标记提供了一个不同的结果行,因此您必须应用一些后处理将其转换为带有标记的文章列表。但是,通过按文章ID排序,您可以确保一篇文章的所有标记一起返回。