如何使用Eloquent和MySQL按最后一个ID排序分组结果?

时间:2015-01-05 16:17:14

标签: php mysql laravel sql-order-by eloquent

我尝试了此查询,但它只订购id列,其余时间不是。

$chapters = Test::select(DB::raw('*, max(id) as id'))
        ->groupBy('id_equip')
        ->orderBy('id', 'asc')
        ->get();

1 个答案:

答案 0 :(得分:7)

MySQL 中使用group by时,您不能依赖order by子句(它不会按预期工作,即它会不< / strong>按组排序结果,而是从组中返回随机行。)

因此,为了实现您的目标,您需要subqueryjoin

// assuming tests table, group by id_equip, order by id
SELECT * FROM tests WHERE id = (
   SELECT MAX(id) FROM tests as t WHERE t.id_equip = tests.id_equip
) ORDER BY id

SELECT * FROM tests 
   JOIN (SELECT MAX(id) as id FROM tests ORDER BY id DESC) as sub
      ON sub.id = tests.id

这将为每个id获得最高id_equip,并为每个Test::where('id', function ($sub) { // subquery $sub->selectRaw('max(id)') ->from('tests as t') ->where('t.id_equip', DB::raw('tests.id_equip')); // order by })->orderBy('id', 'desc')->get(); 返回整行。


现在,如果您希望它看起来更直观,我建议采用第一种方法:

Test::join( DB::raw(
    '(select max(id) as id from tests group by id_equip order by id desc) sub'
  ), 'sub.id', '=', 'posts.id')
  ->get(['tests.*']);

但如果您有大表扫描(就性能而言),可能会采用第二种方法:

order by

这里需要在raw join语句中设置$sub = Test::selectRaw('max(id)') ->groupBy('id_equip') ->orderBy('id', 'desc') ->toSql(); Test::join( DB::raw( "({$sub}) as sub" ), 'sub.id', '=', 'posts.id') ->get(['tests.*']); 子句。

如果您愿意,也可以使用构建器构建该子查询:

{{1}}