>我目前有一个函数:
Score::whereIn('site_id', $sites)
->where('type', 1)
->avg('score');
但目前,如您所见,它在分数表中的所有结果中平均。我只想对每个$site_id
的最新行进行平均(不过,该表可能没有所有 $site_id 在结果中)。
该表有一个created_at
列,该列将按日期/时间确定哪个是最新的。
使用orderBy('created_at', 'DESC')
并使用take(15)
限制结果。这将采用表中最近的 15 条记录。
Score::whereIn('site_id', $sites)
->where('type', 1)
->orderBy('created_at', 'DESC')
->take(15)
->avg('score');
关于take()和orderBy()的文档。
您可以添加groupBy
:
Score::whereIn('site_id', $sites)
->where('type', 1)
->orderBy('created_at', 'desc')
->groupBy('site_id')
->avg('score');
我不确定是否有一种简单的方法可以使用 Laravel 的活动记录样式查询生成器来做到这一点。
一直以来,我都做过这样的事情,它需要一个子查询或一个临时表,因为 GROUP BY(特别是在 MySQL 中)将在分组完成后遵循 ORDER BY,这意味着您无法保证预分组为分组选择的值是符合您的 ORDER BY 的值。
在这种情况下,我认为您实际上可能需要 2 个子查询:第一个对行进行排序以进行分组,第二个进行分组,以便每个site_id有 1 行,最后一个选择进行平均。如果您只执行第一个子查询,则最终将得到每个site_id的平均值,而不是所有site_id的平均值。
这是我认为您正在寻找的内容的示例查询:
SELECT AVG('score') FROM (
SELECT * FROM (
SELECT * FROM table_name ORDER BY created_at DESC
) AS tbl GROUP BY site_id
) AS tbl2;
这是未经测试的,但我认为它通常是正确的。
。所有这些都假设我已经正确解释了这个问题,希望我做到了。
我希望我有一个比 2 个子查询更好的建议 - 如果其他人有更好的方法来做到这一点,我很想学习一些新的东西。
现在,使用 Laravel 的活动记录样式查询构建器执行此操作是我必须去查找以查看是否可能的事情。可能只需要运行原始查询。但我想我会发布该方法,看看它是否合理,然后再进一步挖掘。