使用查询生成器进行分组,就好像它是一个集合一样

问题描述 投票:0回答:2

我正在开发一个 Laravel 应用程序,需要对一组项目执行

groupBy
,例如
groupBy
在集合上执行此操作,但是在获取数据后对集合执行此操作将不起作用,因为我需要使用以下命令来缩小结果查询生成器,之后
groupBy
将不会做任何有用的事情。我知道查询生成器
groupBy
和集合
groupBy
做不同的事情。有没有办法用查询生成器或
groupBy
来完成集合上的
SQL
的操作?

我一直在谷歌上搜索各种东西,玩弄查询,并询问

Bard
,但什么也没得到,似乎
sql
组的做法有所不同。

php sql laravel group-by
2个回答
1
投票

简短的回答是否定的。

SQL 只能返回一组二维结果。将

GROUP BY
更多地视为聚合而不是实际分组可能会有所帮助。

使用 Laravel 的集合,group 方法会获取共享您分组依据的值的记录,并将集合组织成一系列子集合。它只关心分组依据的数据。

使用 SQL,更多是将多个记录合并到一行中的情况,它需要知道如何处理未分组的值。假设您有一个地址表:

城市 街道 数字
伦敦 牛津街 100
伦敦 牛津街 101
伦敦 卡纳比街 200
伦敦 卡纳比街 201
布里斯托尔 玉米街 302

如果我按城市分组,SQL 希望返回两条记录(伦敦和布里斯托尔),因此我需要使用

GROUP_CONCAT()
MAX()
之类的内容聚合剩余的列,或者通过将结果添加到组中来进一步划分结果参数。

如果我按城市 街道分组,那么它会给我 3 条记录(伦敦/牛津街、伦敦/卡纳比街和布里斯托尔/玉米街),所以我只需要聚合数字列。

long答案是肯定的,但您必须将分组数据操作为 json 对象,以便可以为每行的列返回单个值。 请参阅:如果子查询在 MySQL 中返回多于 1 行,如何将 JSON 放入列数据中

听起来您需要在查询上设置过滤器,以便在使用集合对结果进行分组之前可以限制结果集


0
投票

最初的问题并未涵盖完整的上下文,但听起来您的目标是为表中的每个

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();
© www.soinside.com 2019 - 2024. All rights reserved.