将GROUP_CONCAT值作为单个值

时间:2011-01-07 23:07:55

标签: php sql mysql

我正在尝试实现一个简单的标记系统(在php中搞乱)......

我使用以下sql命令获取所需的线程,其作者以及与之关联的标记:

$thread = select_Query("SELECT thread.title, thread.id as t_id,
                         thread.content, author.username, author.id as a_id,
                         GROUP_CONCAT(DISTINCT tags.name ORDER BY tags.name DESC SEPARATOR ',') AS tags
                         FROM thread JOIN thread_tags ON thread.id = thread_tags.thread_id
                         JOIN tags ON thread_tags.tag_id = tags.id
                         INNER JOIN author on author.id = thread.author_id
                         WHERE thread.id = $id", $link);

如您所见,我正在使用GROUP_CONCAT。这工作正常,但是当我这样做时,标签都出现在一个变量中,我知道我可以使用$pieces = explode(",", $thread['tags]); 但是有另一种方法吗?我问这个是因为标签很容易分开但是如果它更复杂(例如包含分隔符的东西)。

我的数据库架构如下:

  

thread:id,content,title,author_id

     

thread_tags:id,tag_id,thread_id

     

标签:id,name

3 个答案:

答案 0 :(得分:2)

您可以将GROUP_CONCAT使用的分隔符更改为不会出现在代码中的内容,也可以是“|”字符。

GROUP_CONCAT(DISTINCT tags.name ORDER BY tags.name DESC SEPARATOR '|')

您还可以验证标记字段,并确保它不包含分隔符。

答案 1 :(得分:1)

大多数标记系统对标记中哪些字符可以或不可以有一组固定的要求。你可以在你的标签中禁用,个字符,它可以正常工作。

答案 2 :(得分:1)

不要试图将多个值压缩到单个单元格中。这不是SQL的设计使用方式,正如您正确指出的那样,如果您的分隔符显示为其中一个值,则可能会导致问题。

幸运的是,有一种方法可以通过重写您的查询来解决这个问题。解决方案是在单元格中返回多行而不是多个值。实际上,您规范化结果集。

换句话说,而不是:

1 tag_1,tag_2,tag_3
2 tag_2,tag_4,tag_5

这样做:

1 tag_1
1 tag_2
1 tag_3
2 tag_2
2 tag_4
2 tag_5

天真地执行此操作可能会导致其他列重复相同的值,如果这些列可能包含大量数据,则可能会浪费不必要的带宽。解决方法是使用两个查询。

换句话说,而不是:

1 foo bar tag_1
1 foo bar tag_2
1 foo bar tag_3
2 baz qux tag_2
2 baz qux tag_4
2 baz qux tag_5

这样做:

Result 1:
1 foo bar
2 baz qux

Result 2:
1 tag_1
1 tag_2
1 tag_3
2 tag_2
2 tag_4
2 tag_5

现在您的结果集处于正常状态。另请注意,您不再需要运行DISTINCT操作,因为结果已经不同。事实上,这两个查询与原始数据库表更加匹配,因此查询可以更简单,并且运行速度更快。