如何使用 Eloquent 和 MySQL 按最后一个 ID 对分组结果进行排序?
How to order grouped results by last id using Eloquent and MySQL?
我试过这个查询,但它只排序 id
列,其余的不是。
$chapters = Test::select(DB::raw('*, max(id) as id'))
->groupBy('id_equip')
->orderBy('id', 'asc')
->get();
在MySQL中使用group by
时你不能依赖order by
子句(它不会像你期望的那样工作,即,它将不是分组排序结果,而是return随机组中的行)。
所以为了达到你想要的效果,你需要subquery
或join
:
// 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_equip
的最高 id
和每个 return 整行。
现在,在 eloquent 我建议第一种方法,如果你想让它看起来更直观:
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();
但是如果你有大 table 扫描(就性能而言),则可能是第二种方法:
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
子句。
如果愿意,您也可以使用构建器构建连接子查询:
$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.*']);
我试过这个查询,但它只排序 id
列,其余的不是。
$chapters = Test::select(DB::raw('*, max(id) as id'))
->groupBy('id_equip')
->orderBy('id', 'asc')
->get();
在MySQL中使用group by
时你不能依赖order by
子句(它不会像你期望的那样工作,即,它将不是分组排序结果,而是return随机组中的行)。
所以为了达到你想要的效果,你需要subquery
或join
:
// 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_equip
的最高 id
和每个 return 整行。
现在,在 eloquent 我建议第一种方法,如果你想让它看起来更直观:
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();
但是如果你有大 table 扫描(就性能而言),则可能是第二种方法:
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
子句。
如果愿意,您也可以使用构建器构建连接子查询:
$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.*']);