Php SQL连接返回重复的数据,并与SQL查询发生冲突
我一直在回归测试我最近开发的公告板。我在SQL查询中遇到了一个小错误Php SQL连接返回重复的数据,并与SQL查询发生冲突,php,mysql,sql,join,duplicates,Php,Mysql,Sql,Join,Duplicates,我一直在回归测试我最近开发的公告板。我在SQL查询中遇到了一个小错误 SELECT `user`.avatar, `user`.username, `user`.id AS user_id, `post`.title, `post`.id, `post`.date AS post_date, `comment`.date AS last_comment_date FROM `post` INNER JOIN `user` ON `post`.user_id = `user`.id
SELECT `user`.avatar, `user`.username, `user`.id AS user_id, `post`.title,
`post`.id, `post`.date AS post_date, `comment`.date AS last_comment_date
FROM `post`
INNER JOIN `user` ON `post`.user_id = `user`.id
LEFT JOIN `comment` ON `post`.id = `comment`.post_id
WHERE `post`.category_id = 1
ORDER BY IFNULL(`last_comment_date`, `post_date`) DESC;
将产生类似的结果
我碰巧知道这件事的原因。MySQL将所有评论与他们的帖子连接起来,换句话说,这是一对多的关系,一篇帖子可以有很多评论。这就产生了分页问题,因为前十篇文章可能是相同的,这取决于它是否有十条评论。我恰好只需要comment
表中的最新注释日期
我遇到了几个解决方案
- Group by
,但它与行分组后执行的order by不一样post.id
- 检索整个结果集并对PHP所需内容进行排序。使用这种方法,我可能会受到巨大的性能打击
- 执行多个查询,但这不是我们的想法
- 做一个子查询,但我不知道这是否是一个坏习惯
SELECT `user`.avatar, `user`.username, `user`.id AS user_id, `post`.title, `post`.id,
`post`.date AS post_date, MAX(`comment`.date)
FROM `post`
INNER JOIN `user` ON `post`.user_id = `user`.id
LEFT JOIN `comment` ON `post`.id = `comment`.post_id
WHERE `post`.category_id = 1
GROUP BY `post`.id
ORDER BY IFNULL(MAX(`comment`.date), `post_date`) DESC
生产
这似乎正是我想要的。如果帖子有评论,则按最新评论日期排序(如果没有,则按发布日期排序)。我也可以将其用于分页限制
,而无需任何预处理。我是否仍然需要IFNULL
?我想是的
编辑2
还有一个缺陷。如果一篇文章的最后评语日期为空,则排序不正确。如果您参考以下图片。你可以看到,即使发生了碰撞,最后的“评论”日期仍在那里
请忽略下面的内容
编辑3 这就是我想要的
我认为分组是你最好的选择。只需按除comment.date之外的所有选定列进行分组,然后使用MAX函数获取最新的注释日期,如下所示:
SELECT
`user`.avatar,
`user`.username,
`user`.id AS user_id,
`post`.title,
`post`.id,
`post`.date AS post_date,
MAX(`comment`.date) AS last_comment_date
FROM
`post` INNER JOIN `user` ON `post`.user_id = `user`.id
LEFT JOIN `comment` ON `post`.id = `comment`.post_id
WHERE
`post`.category_id = 1
GROUP BY
`user`.avatar,
`user`.username,
`user`.id,
`post`.title,
`post`.id,
`post`.date
ORDER BY
IFNULL(`last_comment_date`, `post_date`) DESC;
我知道这并不能直接解决您的问题,但为了将来的参考,请不要使用保留名称,如
user
作为您的列名。您是否尝试过使用MAX()
作为注释日期,然后使用Group by
对其他列进行分组?+1啊,谢谢您的评论!我不知道这是一个保留关键字。D:这就是为什么我打字时会用颜色编码的原因。不管需要什么,我都计划稍微修改一下结构。@Zane你确定user
是保留关键字吗?@Zane请参考我上面的编辑。你是说像那样吗?我还需要ifnull吗?我想我会的,因为不是每个帖子都会有评论,谢谢!我也这么认为。当我在SQL编辑器中键入它时,它会进行颜色编码。这取决于您想要实现什么。现在我只使用了你的原始想法,它按最后评论日期排序,但如果这是空的,则使用发布日期,实际上这就是你的截图显示的内容。也许您想先按最后一个评论日期(结尾为空)排序,然后按发布日期排序?请参见上面的编辑#3,将其与编辑#2中的图像进行比较。这就是我想要的。这在SQL中是可能的吗?我想我已经尝试过按最后评论日期排序,然后按发布日期排序。我试图理解为什么发布id 2排在1之前而不是3之前?对于(1和2),最后一次操作(发布日期或最后评论日期)在发布3之前。所以两者都应该在3之前或之后。对我来说,现在似乎没有顺序。更正:为什么id为3的帖子排在1之前而不是2之前?如果你看,id为2的帖子的评论日期比id为3的帖子的日期更晚。尽管它是在“2014-03-13 13:49:46”创建的,但2的id有一条日期为“2014-03-13 01:09:57”的注释。哦,等等,我的错!我忘了对id为2的帖子发表评论。现在它比id为3的帖子更新。谢谢你的帮助!=)