如何使用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();

不过,如果你有数百万行,这并不理想。