Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/260.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php SQL连接返回重复的数据,并与SQL查询发生冲突_Php_Mysql_Sql_Join_Duplicates - Fatal编程技术网

Php 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

我一直在回归测试我最近开发的公告板。我在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
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
    post.id
    ,但它与行分组后执行的order by不一样

  • 检索整个结果集并对PHP所需内容进行排序。使用这种方法,我可能会受到巨大的性能打击

  • 执行多个查询,但这不是我们的想法

  • 做一个子查询,但我不知道这是否是一个坏习惯

最好的做法是什么?如果连接是一对多关系,是否有任何方法阻止MySQL返回连接上的重复数据

编辑1

正如@Zane所问的,这个SQL查询

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的帖子更新。谢谢你的帮助!=)