显示最后评论每个用户只有1条评论

时间:2016-04-12 15:55:10

标签: mysql greatest-n-per-group

我有一个正常的评论表:

| id | comment | date | user | post | status |

我想用每个用户只有1条评论来获取我的10条评论,我的意思是这样的:

我有这些数据: | id | comment | date | user | post | | 1 | text1 | 2016-04-01| 1 | 1 | | 2 | text2 | 2016-04-02| 2 | 1 | | 3 | text3 | 2016-04-03| 1 | 2 | | 4 | text4 | 2016-04-04| 4 | 3 | | 5 | text5 | 2016-04-04| 3 | 5 | | 6 | text6 | 2016-04-05| 2 | 4 | | 7 | text7 | 2016-04-07| 5 | 3 | | 8 | text8 | 2016-04-10| 4 | 9 | | 9 | text9 | 2016-04-11| 3 | 7 | | 10 | text10 | 2016-04-12| 5 | 8 |

我希望得到这个: | 10 | text10 | 2016-04-12| 5 | 8 | | 9 | text9 | 2016-04-11| 3 | 7 | | 8 | text8 | 2016-04-10| 4 | 9 | | 6 | text6 | 2016-04-05| 2 | 4 | | 3 | text3 | 2016-04-03| 1 | 2 |

我使用这个sql语句:

SELECT  *
FROM  `comments`
GROUP BY  `user` 
ORDER BY MAX(`id`) DESC

这会以正确的用户顺序提取评论,但评论日期的顺序错误: | 7 | text7 | 2016-04-07| 5 | 3 | | 9 | text9 | 2016-04-11| 3 | 7 | | 4 | text4 | 2016-04-04| 4 | 3 | | 6 | text6 | 2016-04-05| 2 | 4 | | 1 | text1 | 2016-04-01| 1 | 1 |

2 个答案:

答案 0 :(得分:1)

为什么它不能与GROUP BY

一起使用

SELECT *不能与GROUP BY一起使用;它是无效的SQL。 GROUP BY不会选择表格行。它使用提供的表达式创建行组,然后从每个组生成新记录,并使用表达式中涉及的值计算此新记录的每一列。

SELECT子句中出现的列必须满足以下规则之一:

虽然*是查询使用的表的所有列名称的快捷方式,但对于您的查询,user列只满足上述要求之一。

Before version 5.7.5 MySQL没有实现上面的第三条规则。它曾用于接受SELECT子句中包含不符合任何GROUP BY要求的列的查询。此类列的查询返回的值为indeterminate

从版本5.7.5开始,MySQL拒绝满足要求的GROUP BY个查询。

解决方案

无论哪种方式,问题的解决方案都不涉及GROUP BY。使用具有正确条件的LEFT JOIN可以轻松完成:

SELECT lc.*
FROM comments lc               # 'lc' from 'last comment'
    LEFT JOIN comments nc      # 'nc' from 'newer comment'
        ON lc.user = nc.user   # both comments belong to the same user
        AND lc.id < nc.id      # 'nc' is newer than 'lc'
WHERE nc.id IS NULL            # there is no 'newer comment'
ORDER BY lc.id DESC
LIMIT 10

如何运作

它加入表格comments,别名为lc(&#34; lc&#34;来自&#34;最后一条评论&#34;用户)对自己,别名为{ {1}}(&#34; nc&#34;来自&#34;较新的评论&#34;)。 join子句将nc的每个条目与lc的所有条目匹配,这些条目属于同一个用户(nc)并且更新(lc.user = nc.user;我假设已分配ID顺序和较新的注释具有较大的lc.id < nc.id}值。

使用id可确保LEFT JOIN的每一行都出现在联接的结果中,即使在lc中找不到匹配的行(因为没有更新的评论)同一个用户)。在这种情况下,使用nc代替NULL的字段。 nc子句仅在最终结果集中保留WHERENULL的行;这意味着在nc.id部分中,它们包含每个用户的最新评论。

lc子句包含SELECT的所有字段(lc的所有字段都是nc,无论如何)。 NULL子句可用于对结果集进行排序。 ORDER BY首先放置最新的注释,ORDER BY lc.id DESC子句将结果集保持适当的大小。

答案 1 :(得分:0)

你可以试试这个:

SELECT u.*
FROM (
    SELECT id,comment,MAX(date) as date,`user`,post,status
    FROM comments 
    GROUP BY `user`) AS t
JOIN comments AS u USING (id)