我正在开发一个 Laravel 应用程序,需要对一组项目执行
groupBy
,例如 groupBy
在集合上执行此操作,但是在获取数据后对集合执行此操作将不起作用,因为我需要使用以下命令来缩小结果查询生成器,之后 groupBy
将不会做任何有用的事情。我知道查询生成器 groupBy
和集合 groupBy
做不同的事情。有没有办法用查询生成器或 groupBy
来完成集合上的 SQL
的操作?
我一直在谷歌上搜索各种东西,玩弄查询,并询问
Bard
,但什么也没得到,似乎sql
组的做法有所不同。
简短的回答是否定的。
SQL 只能返回一组二维结果。将
GROUP BY
更多地视为聚合而不是实际分组可能会有所帮助。
使用 Laravel 的集合,group 方法会获取共享您分组依据的值的记录,并将集合组织成一系列子集合。它只关心分组依据的数据。
使用 SQL,更多是将多个记录合并到一行中的情况,它需要知道如何处理未分组的值。假设您有一个地址表:
城市 | 街道 | 数字 |
---|---|---|
伦敦 | 牛津街 | 100 |
伦敦 | 牛津街 | 101 |
伦敦 | 卡纳比街 | 200 |
伦敦 | 卡纳比街 | 201 |
布里斯托尔 | 玉米街 | 302 |
如果我按城市分组,SQL 希望返回两条记录(伦敦和布里斯托尔),因此我需要使用
GROUP_CONCAT()
或 MAX()
之类的内容聚合剩余的列,或者通过将结果添加到组中来进一步划分结果参数。
如果我按城市 和 街道分组,那么它会给我 3 条记录(伦敦/牛津街、伦敦/卡纳比街和布里斯托尔/玉米街),所以我只需要聚合数字列。
long答案是肯定的,但您必须将分组数据操作为 json 对象,以便可以为每行的列返回单个值。 请参阅:如果子查询在 MySQL 中返回多于 1 行,如何将 JSON 放入列数据中
听起来您需要在查询上设置过滤器,以便在使用集合对结果进行分组之前可以限制结果集
最初的问题并未涵盖完整的上下文,但听起来您的目标是为表中的每个
set_id
选择每 50 条记录。这可以直接在 SQL 中实现,但并不完全简单。
为了获得一致的结果,您需要添加
ORDER BY
。这很重要,因为通常 MySQL 会返回按主键排序的内容,但这并不能保证。
您尝试提出的查询看起来像这样:
SELECT
t.sensor_id,
t.value,
t.set_id
FROM (
SELECT
sensor_id,
value,
set_id,
ROW_NUMBER() OVER (PARTITION BY set_id ORDER BY some_column_here) as rn
FROM
your_table
) as t
WHERE t.rn % 50 = 0; # Assuming you literally meant every 50th row. Otherwise just use "= 50" instead.
这应该转换为 Laravel 中类似的查询:
$results = DB::table('your_table')
->select('sensor_id', 'value', 'set_id')
->selectRaw('ROW_NUMBER() OVER (PARTITION BY set_id ORDER BY some_ordering_column) as rn')
->fromSub(function ($query) {
$query->from('your_table')->selectRaw('sensor_id, value, set_id');
}, 't')
// Replace with `where->('rn', 50)` if you just want the 50th record, not every 50th.
->whereRaw('rn % 50 = 0')
->get();