如何使用Laravel Query Builder从子查询中进行select?
我想通过使用Eloquent ORM的以下SQL来获得价值。
– SQL
SELECT COUNT(*) FROM (SELECT * FROM abc GROUP BY col1) AS a;
然后我考虑以下。
– 代码
$sql = Abc::from('abc AS a')->groupBy('col1')->toSql(); $num = Abc::from(\DB::raw($sql))->count(); print $num;
我正在寻找更好的解决scheme。
请告诉我最简单的解决scheme。
除了@ delmadord的回答和你的评论:
目前,在FROM
子句中没有创build子查询的方法,所以您需要手动使用原始语句,如有必要,您将合并所有绑定:
$sub = Abc::where(..)->groupBy(..); // Eloquent Builder instance $count = DB::table( DB::raw("({$sub->toSql()}) as sub") ) ->mergeBindings($sub->getQuery()) // you need to get underlying Query Builder ->count();
请注意,您需要按正确的顺序合并绑定 。 如果你有其他的绑定子句,你必须把它们放在mergeBindings
之后:
$count = DB::table( DB::raw("({$sub->toSql()}) as sub") ) // ->where(..) wrong ->mergeBindings($sub->getQuery()) // you need to get underlying Query Builder // ->where(..) correct ->count();
@JarekTkaczyk的解决scheme正是我所期待的。 我唯一想念的是如何在使用DB::table()
查询时做到这一点。 在这种情况下,我就是这么做的:
$other = DB::table( DB::raw("({$sub->toSql()}) as sub") )->select( 'something', DB::raw('sum( qty ) as qty'), 'foo', 'bar' ); $other->mergeBindings( $sub ); $other->groupBy('something'); $other->groupBy('foo'); $other->groupBy('bar'); print $other->toSql(); $other->get();
特别注意如何在不使用getQuery()
方法的情况下制作mergeBindings
我喜欢做这样的事情:
Message::select('*') ->from(DB::raw("( SELECT * FROM `messages` WHERE `to_id` = ".Auth::id()." AND `isseen` = 0 GROUP BY `from_id` asc) as `sub`")) ->count();
这不是很优雅,但很简单。
我不能让你的代码做所需的查询,AS只是表abc
的别名,而不是派生表。 Laravel查询生成器不隐式支持派生的表别名,DB :: raw很可能需要这个。
我能想出的最直接的解决scheme几乎与您的相同,但是按照您的要求生成查询:
$sql = Abc::groupBy('col1')->toSql(); $count = DB::table(DB::raw("($sql) AS a"))->count();
生成的查询是
select count(*) as aggregate from (select * from `abc` group by `col1`) AS a;
你需要子查询吗? 你可以尝试类似的东西
$num = Abc::groupBy('col1')->get()->count();
不过,如果你有数百万行,这并不理想。