【发布时间】:2011-03-21 12:59:56
【问题描述】:
我有两个具有以下结构的表:
文章:article_id,文本 标签:tag_id、article_id、文本
如何通过一次查询选择所有文章和所有相关标签?据我所知,MySQL 只能返回一个二维数组,所以我可以一个解决方案是将所有标签连接到文章选择结果的列中。但是怎么做呢?
【问题讨论】:
我有两个具有以下结构的表:
文章:article_id,文本 标签:tag_id、article_id、文本
如何通过一次查询选择所有文章和所有相关标签?据我所知,MySQL 只能返回一个二维数组,所以我可以一个解决方案是将所有标签连接到文章选择结果的列中。但是怎么做呢?
【问题讨论】:
关系数据以元组的形式组织。元组有 n 维,并且可以很容易地描述从 m 维向量到具有单个关系(表)的标量或 k 维值的功能映射。 (n = m + k)
如果您需要/建议的只是表示层,那么您可以按照 Eric Hogue 的建议进行操作,但如果这是在某个过程的中间或另一个过程的开始,那么 Fabrik 的建议是正确的方法。
GROUP_CONCAT 使数据成为非关系数据,因此更难用作 SQL 后续处理的基础。因此,如果您的客户端层无法为您执行此命令,则此命令的目的是使输出具有针对性。不要试图根据表现问题来建模你的核心关系。
【讨论】:
看看Group_Concat MySQL 函数。你可以写类似
Select A.article_id, A.text GROUP_CONCAT(B.Text) As Tags
From articles A
Left Outer Join tags B Using (article_id)
Group By A.article_id, A.Text
正如 Unreason 在他的回答中提到的,这应该只在你想显示数据时使用,我建议它,因为你提到在问题中连接标签。如果您需要处理日期,请按照 fabrik 的建议使用简单的连接。
【讨论】:
SELECT * FROM articles LEFT JOIN tags ON article.article_id = tags.article_id
【讨论】:
如果您按文章排序,那么您可以通过跳过与重复文章 ID 关联的文章属性来创建数据表示 - 或者只是覆盖它们:
// select a.article_id, a.text, b.tag_id, b.text as tag_text
// from articles a, tags b
// where a.article_id=b.article_id
$articles=array();
while ($r=mysql_fetch_assoc($result)) {
$article[$r['article_id']=array(
'text'=>$r['text'];
);
@if (!is_array($article[$r['article_id']]['tags'])) {
$article[$r['article_id']]['tags']=array();
}
$article[$r['article_id']]['tags'][$r['tag_id']]=$r['tag_text'];
}
【讨论】: