按字段最大值过滤重复项
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.id
和users.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以上是关于按字段最大值过滤重复项的主要内容,如果未能解决你的问题,请参考以下文章