4

我正在尝试创建一个包含帖子列表的页面,并在每个帖子下方包含属于该帖子的所有评论。最初,我只想使用一个查询来使用 SQL 的 JOIN 检索所有帖子 + 评论,但我发现例如检索具有多个评论的帖子是不可能的。它仅显示每个帖子最多 1 条评论的帖子,或者根据评论数量仅显示帖子多次。

在这个相关问题中,有人谈到了使用 2 个查询: How to print posts and comments with only a sql query

但是我该怎么做呢?

我有帖子的查询和while循环,但我显然不想为该循环内的每个帖子运行评论查询。

$getPost = mysql_query('SELECT p.post_id,
                               p.user_id,
                               p.username,
                               p.content
                        FROM post p
                        ORDER BY p.post_id DESC');

while($row = mysql_fetch_array($getPost)) 
{ 
... 
}

表结构(reply为存放评论的表):

POST (post_id (primary key), user_id, username, content, timestamp)
REPLY (reply_id (primary key), post_id, username, reply_content, timestamp)
4

2 回答 2

4

您可以在单个查询中执行此操作,如果原始帖子中的数据量很小,则可以:

$getPost = mysql_query('SELECT
  p.*,
  r.reply_id, r.username r_username, r.reply_content, r.timestamp r_timestamp
  FROM post p
    left join reply r
  ORDER BY p.post_id DESC'
);

$posts = array();
$last_id = 0;
while($row = mysql_fetch_array($getPost)) 
{ 
  if ($last_id != $row['post_id']) {
    $posts[] = array(
      'post_id' => $row['post_id'],
      'user_id' => $row['user_id'],
      'username' => $row['username'],
      'content' => $row['content'],
      'timestamp' => $row['timestamp'],
      'comments' => array()
    );
  }

  $posts[sizeof($posts) - 1]['comments'][] = array(
    'reply_id' => $row['reply_id'],
    'username' => $row['r_username'],
    'reply_content' => $row['reply_content'],
    'timestamp' = $row['r_timestamp']
  );
}

否则,将其分成两个查询,如下所示:

$getPost = mysql_query('SELECT
  p.*,
  FROM post p
  ORDER BY p.post_id DESC'
);

$rows = array();
$ids = array();
$index = array();
while($row = mysql_fetch_assoc($getPost)) {
  $row['comments'] = array();
  $rows[] = $row;
  $ids[] = $row['post_id'];
  $index[$row['post_id']] = sizeof($rows) - 1;
}

$getComments = mysql_query('select r.* from replies r where r.post_id in ("'
  . join('","', $ids)
  . '")');
while ($row = mysq_fetch_assoc($getComments)) {
  $rows[$index[$row['post_id']]]['comments'][] = $row;
}

... 或类似的东西。任何一个选项都可以让您在第一个查询中添加 WHERE 子句等等,随心所欲。第二种方法的优点是您不会为每个评论重新传输原始帖子数据!

于 2012-11-27T16:16:53.687 回答
1

为了也获得那些没有评论的帖子,您需要使用LEFT OUTER JOIN. 在这种情况下,第一个表中没有第二个表中任何对应行的任何行都将与由空值组成的行配对。

SELECT *  FROM posts
LEFT OUTER JOIN comments ON posts~post_id = comments~post_id;

顺便说一句:还有一个RIGHT OUTER JOIN。当您使用它时,您将获得所有评论,包括那些父帖子以某种方式丢失的评论,但没有没有评论的帖子。

于 2012-11-27T16:00:50.603 回答