Laravel 选择列,然后按日期对列值进行分组

Posted

技术标签:

【中文标题】Laravel 选择列,然后按日期对列值进行分组【英文标题】:Laravel select columns and then group column value by date 【发布时间】:2021-06-02 22:45:44 【问题描述】:

我正在尝试在我的 Laravel 项目中使用看似简单的 SQL 查询,我有一个前端 Web 应用程序,它允许用户从各种预定义的表中提取数据和一个可选的列列表。

如果我不尝试将selectgroupBy 放在一起,这可以正常工作,同样,我需要根据用户是想按天还是按月对数据进行分组来进行分组。

我的 POST 请求看起来像,其中父数组中的每个数组项都是一个表:

[
  [
    table: 'my_table',
    columns: ['event_category', 'event_action', 'event_count', 'created_at'] ...
    filterBy: [
      ['event_category', 'my category'],
      ['event_action', 'some action']
    ],
    orderBy: 
      field: 'created_at',
      direction: 'desc'
    
  ]
]

my_table 中的每一行都包含一个 event_count 列,其中包含一个数字,因此如果特定日期有 5 行具有不同的 event_count 数字,我需要将所有这些 event_count 条目加起来并按那一天

对它们进行分组

这是我的函数和查询:

public function findDataFromSources(Request $request)


    $request_data = $request->all();
    $realData = [
      'size' => 0,
      'results' => [],
      'filtered' => []
    ];

    foreach ($request_data as $key => $findable) 
      // NOTE: this works for retrieving data that isn't grouped
      // $res = DB::table($findable['table'])
      //          ->select($findable['columns'])
      //          ->where($findable['filterBy'])
      //          ->orderBy($findable['orderBy']['field'], $findable['orderBy']['direction'])
      //          ->take(20)
      //          ->get();

      // TODO: this isn't grouping for some reason...
      $res = DB::table($findable['table'])
              ->select($findable['columns'], DB::raw('sum(event_count) as total_events'))
              ->groupBy('created_at')
              ->orderBy($findable['orderBy']['field'], $findable['orderBy']['direction'])
              ->get();

      $realData['size'] += count($res);
      array_push($realData['results'], $res);
    

    $data = [
      'success' => true,
      'message' => 'Your chosen data sources and fields',
      'sources' => $realData
    ];


我错过了什么?我得到的错误是:

SQLSTATE[42000]:语法错误或访问冲突:1055 SELECT 列表的表达式 #1 不在 GROUP BY 子句中并且包含非聚合列

【问题讨论】:

尝试像这样在选择的方法中添加 created_at :- ->select('created_at', $findable['columns'], DB::raw('sum(event_count) as total_events') ) 因为当您尝试将行与特定列分组时,您应该在 select 方法中添加它。 这可能会帮助你***.com/a/66356459/3341543 不完全确定该解决方案 @RobbinBenard 是否对我有用,也许我误解了其中的 selectRaw 部分,我的 selectRaw 现在是:->selectRaw($findable['columns'], 'ANY_VALUE(event_count)', 'COUNT(*) AS total_events') 这给了我一个错误它需要是一个数组 【参考方案1】:
->select($findable['columns']

您不能在没有聚合函数的情况下 SELECT 不在 GROUP BY 中的字段/列,并且您的 $findable['columns'] 可能包含不在 GROUP BY 中的字段。

您可以使用ANY_VALUE(),例如@RobbinBenard 评论

->select(DB::raw('ANY_VALUE(' .$findable['columns'][0] .')'))

您可以遍历列并使用addSelect() 添加这些列。

  $query = DB::table($findable['table'])
          ->select(DB::raw('sum(event_count) as total_events'));

  foreach($findable['columns'] as $column) 
          $query->addSelect(DB::raw('ANY_VALUE(' .$column .')'));
  

  $res = $query->groupBy('created_at')
         ->orderBy($findable['orderBy']['field'], $findable['orderBy']['direction'])
         ->get();

【讨论】:

太棒了,但在您的示例中,您要从数组中选择第一个,我需要选择所有这些,然后按特定列分组 @RyanH 你可以遍历你的列并添加到查询中,查看更新的代码

以上是关于Laravel 选择列,然后按日期对列值进行分组的主要内容,如果未能解决你的问题,请参考以下文章

Excel—分组然后取每组中对应时间列值最大的或者最小的

Laravel:如何通过选择两列进行分组具有不同的值

如何仅按某个列值的前几个字母对 SQL 查询进行分组?

Pandas:如何根据其他列值的条件对列进行求和?

Pandas 按值 1 对列进行分组并按频率排序

Laravel 每天按奇数小时对数据进行分组