如何检索具有1:N关系的列表

时间:2011-05-29 20:21:15

标签: mysql sql

我有一个'文章'表,我有一个'标签'表。两者之间存在N:N关系,所以我也有'articles_tags_relations'表。我想检索带有标签的文章列表,但是除了标签的名称之外,我也需要它的ID。所以返回的数据应该是(当然不是JSON格式):

[[1,"FirstArticle",{"1":"FirstTag","2":"SecondTag"}],[2,"SecondArticle",{"3":"ThirdTag"}]]

到目前为止,我有类似的内容:

SELECT article.*, GROUP_CONCAT(tag.name SEPARATOR ', ') AS tags FROM articles AS article LEFT JOIN articles_tags_relations AS relation ON article.id = relation.article_id LEFT JOIN tags AS tag ON relation.tag_id = tag.id LIMIT 0,10;

但它只有没有id的标签名称。桌面上会有很多读取查询,因此性能很重要。我不确定使用GROUP_CONCAT是否可行,我对任何想法持开放态度。谢谢!

4 个答案:

答案 0 :(得分:1)

您是否必须在一个查询中执行此操作?我会做一个查询来获取文章,然后第二个查询来获取这些文章ID的标记。我不确定性能如何比较。 (并且它可能取决于您的网络速度,第二个查询与左连接的成本。)

也就是说,尝试在sql查询中连接多个数据片段时感觉它违背了关系数据库的精神,并且不太可能像数据库真正擅长的那样执行。

答案 1 :(得分:1)

据我所知,GROUP_CONCAT()GROUB BY条款一起使用。但是,以下是使用您的数据接收tag.id的两种方法:

SELECT article.*, tag.id AS tags_id, GROUP_CONCAT(tag.name SEPARATOR ', ') AS tags FROM articles AS article LEFT JOIN articles_tags_relations AS relation ON article.id = relation.article_id LEFT JOIN tags AS tag ON relation.tag_id = tag.id LIMIT 0,10;

而且2:

SELECT article.*, GROUP_CONCAT(tag.name SEPARATOR ', ') AS tags, GROUP_CONCAT(tag.id SEPARATOR ', ') AS tag_ids FROM articles AS article LEFT JOIN articles_tags_relations AS relation ON article.id = relation.article_id LEFT JOIN tags AS tag ON relation.tag_id = tag.id LIMIT 0,10;

答案 2 :(得分:0)

抱歉,我似乎无法理解你的问题。对我而言,解决方案很简单:select a.id, a.name, t.id, t.name from articles a, tags t, articles_tags_relations atr where a.id = atr.article_id and t.id = atr.tag_id

当然,这并不是您想要的格式化结果,但格式化不是SQL的意思。首先检索结果(见上文),然后使用您选择的编程语言格式化结果集。

答案 3 :(得分:0)

你快到了。添加CONCAT以获取ID并一起记录,或为每个创建单独的GROUP_CONCAT子句。

SELECT article.*, 
  GROUP_CONCAT(CONCAT(tag.id,':',tag.name)) AS tags 
FROM articles AS article 
LEFT JOIN articles_tags_relations AS relation ON article.id = relation.article_id 
LEFT JOIN tags AS tag ON relation.tag_id = tag.id
GROUP BY article.id 
LIMIT 0,10

AFAIK没有什么特别的GROUP_CONCAT会导致性能下降。


只是为了好玩,这里有一个返回JSON的查询

SELECT CONCAT('[',GROUP_CONCAT(CONCAT('[',row_data,']')),']') as JSON
FROM
(
  SELECT CONCAT(a.id,',"',a.title,'",{',GROUP_CONCAT(CONCAT("'",tag.id,'":"',tag.name,'"')),'}') as row_data
  FROM articles AS a 
  LEFT JOIN articles_tags_relations AS relation ON a.id = relation.article_id 
  LEFT JOIN tags AS tag ON relation.tag_id = tag.id
  GROUP BY a.id 
  LIMIT 0,10 
) t1