按字段最大值过滤重复项

Posted

技术标签:

【中文标题】按字段最大值过滤重复项【英文标题】:Filter duplicates by field max value 【发布时间】:2019-11-09 13:05:25 【问题描述】:

我在获取数据时遇到问题。我试图让所有用户都有最大值(点)。我的问题就像OData filter by max value and field。

我的问题的代码是:

 $query = User::select('users.id','users.username','games.points', 
 'games.created_at')
            ->join('games', 'users.id', '=', 'games.user_id')
            ->whereBetween('games.created_at', [$start, $end]);

但问题是当我想删除重复项并为每个用户获得最高分时。

在我不需要 whereBetween 的版本中我是这样做的:

 return User::select('users.id', 'users.username', 'games.points', 
                     'games.created_at')
            ->join('games', 'users.id', '=', 'games.user_id')
            ->whereRaw('(users.id, games.points) IN (SELECT user_id, MAX(points)                
                        FROM games GROUP BY user_id)')
            ->orderByDesc('points')
            ->get();

谢谢

【问题讨论】:

那么,您想要的是每个用户游戏的最大积分数? @Lucas 准确但在日期范围内(whereBetween) 【参考方案1】:

您为什么不简单地GROUP BY 您对users.idusers.username 的查询?

-- I let you translate the query into your framework
SELECT users.id, users.username, max(games.points) as points
FROM users, games
WHERE users.id = games.user_id
AND games.created_at BETWEEN $start AND $end
GROUP BY users.id, users.username
ORDER BY max(games.points) DESC

这样,您将获得每个用户(ID 和用户名)的最大积分。

希望这会有所帮助。

【讨论】:

因为我还需要created_at字段在select中 我明白了。但是那样的话,就不能在->whereRaw后面加上->whereBetween('games.created_at', [$start, $end]);吗? 是的,我可以添加,但我还需要选择 created_at,因为我需要来自 db 的数据中的信息(日期)。 嗯,我想我得到了你想要做的事情。给我一点时间,我会想出一个答案 我正在解决这个问题。我会在几分钟内提供答案。非常感谢卢卡斯!【参考方案2】:

我已经用 eloquent 的独特方法解决了我的问题。

Game::with('user')
            ->whereBetween('created_at', [$start, $end])
            ->orderByDesc('points')
            ->orderBy('created_at')
            ->limit($limit)
            ->get()
            ->unique('user_id')
            ->values();

非常感谢 Lucas 的宝贵时间和帮助。

【讨论】:

酷。我正要发布相同的答案:) @Lucas 有趣的是我的查询不能正常工作。我在数据库中有 3 个用户(测试目的),今天这 3 个用户中有 2 个玩游戏,ID 为 4 的用户玩了两次游戏,ID 为 5 的用户玩了一次游戏。查询返回我只是 id 为 5 的用户。你知道如何调试它吗? 我创建了一个dbfiddle,它似乎可以工作。随意玩它 @Lucas 我已经更新了创建表和插入数据以及 where 子句的时间跨度,请检查我的结果。有重复的用户数据。你知道如何解决这个问题吗? @Lucas 这里更新了dbfiddle

以上是关于按字段最大值过滤重复项的主要内容,如果未能解决你的问题,请参考以下文章

通过另一个字段选择具有最大日期顺序的数据[重复]

Postgresql 查找每个类型的最大 transaction_id 给出重复项(当它不应该用于 PK 时)

sqlite3 按最大值查询并按第二个因素过滤

删除列表中的最大值,保留重复项

通过排序和过滤删除重复项

使用postgresql TEXT类型按字段排序时如何删除重复项?