关于取每个用户最新一条留言去重的问题

忍不住还是开口了。

表一 messages

id (PRIMARY KEY)、to_user_id、from_user_id、content、created_at

表二 user

id (PRIMARY KEY)、name、created_at

查询当天最新的 messages 并分页,要求同 user 只取一条 messages;

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 10

不是用 group 就好了吗?

5年前 评论
waney (楼主) 5年前
全场我最姜姜姜丶 5年前
_Daniel (作者) 5年前

使用 DISTINCT 用户ID

5年前 评论
waney (楼主) 5年前

使用 keyBy (' 用户 ID ')

5年前 评论
waney (楼主) 5年前

试试跟据 from_user_id 分组获得本组最大自增 id,然后再 in 出来呢。数据量大可能会是个坑,但如果每日几万条数据应该是没问题的,配合 created_at 索引使用。

SELECT * FROM message WHERE id IN (SELECT MAX(id) message test GROUP BY from_user_id);
5年前 评论
waney (楼主) 5年前
yichengo (作者) 5年前
waney (楼主) 5年前
yichengo (作者) 5年前
waney (楼主) 5年前
yichengo (作者) 5年前
yichengo (作者) 5年前
waney (楼主) 5年前

增加一个字段 is_user_latest, 代表是否这个用户最新一条评论
就 OK 了

5年前 评论
waney (楼主) 5年前
JerryBool (作者) 5年前
waney (楼主) 5年前
yichengo 5年前
全场我最姜姜姜丶 5年前

SELECT max(created_at),from_user_id,content from messages WHERE created_at like "%2019-08-21%" GROUP BY from_user_id ORDER BY from_user_id desc limit 100;


不知道这个能适应你的需求不;

5年前 评论
wuyan94zl 5年前
littlehero (作者) 5年前
yichengo 5年前
littlehero (作者) 5年前
waney (楼主) 5年前
yichengo 5年前
小猪蹄子 5年前

SELECT
    `t`.*
FROM
    (
        SELECT
            `m`.`id`,
            `m`.`to_user_id`,
            `m`.`from_user_id`,
            `u`.`name`,
            `m`.`content`,
            `m`.`created_at`
        FROM
            `messages` AS m,
            `user` AS u
        WHERE
            `m`.`to_user_id` = `u`.`id`
        ORDER BY
            `m`.`created_at` DESC
    ) AS t
GROUP BY
    `t`.`to_user_id`
LIMIT 0,20
5年前 评论

关于 group by 组内排序的问题,mysql 官方文档有讲
https://dev.mysql.com/doc/refman/5.6/en/gr...
MySQL extends the standard SQL use of GROUP BY so that the select list can refer to nonaggregated columns not named in the GROUP BY clause. This means that the preceding query is legal in MySQL. You can use this feature to get better performance by avoiding unnecessary column sorting and grouping. However, this is useful primarily when all values in each nonaggregated column not named in the GROUP BY are the same for each group. The server is free to choose any value from each group, so unless they are the same, the values chosen are nondeterministic. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause. Result set sorting occurs after values have been chosen, and ORDER BY does not affect which values within each group the server chooses.
结论就是除非记录完全相同,否则 mysql 不保证每次 group by 结果相同

5年前 评论

我这样做,效果已达到。

DB::table('messages as t1')
  ->leftJoin('messages as t2', function ($join) {
    $join->on('t1.from_user_id', '=', 't2.from_user_id')->on('t1.id', '<', 't2.id');
})
  ->leftJoin('user as t3', 't1.from_user_id', '=', 't3.id')
  ->where('t1.to_user_id', $id)
  ->whereNull('t2.id')->paginate(15);
5年前 评论