sql - wheredate - ¿Cómo seleccionar desde la subconsulta utilizando Laravel Query Builder?
wheredate laravel (5)
Me gustaría obtener valor con el siguiente SQL usando Eloquent ORM.
- SQL
SELECT COUNT(*) FROM
(SELECT * FROM abc GROUP BY col1) AS a;
Entonces consideré lo siguiente.
- Código
$sql = Abc::from(''abc AS a'')->groupBy(''col1'')->toSql();
$num = Abc::from(/DB::raw($sql))->count();
print $num;
Estoy buscando una mejor solución.
Por favor dígame la solución más simple.
Además de la respuesta de @ delmadord y sus comentarios:
Actualmente no existe un método para crear una subconsulta en la cláusula FROM
, por lo que debe usar manualmente el comando Raw y luego, si es necesario, fusionará todas las vinculaciones:
$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();
Tenga en cuenta que debe fusionar enlaces en el orden correcto . Si tiene otras cláusulas enlazadas, debe ponerlas después de 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();
Desde laravel 5.5 hay un método dedicado para subconsultas y puedes usarlo así:
Abc::subSelect(function($q) { $q->select(''*'')->groupBy(''col1''); }, ''a'')->count(''a.*'');
o
Abc::subSelect(Abc::select(''*'')->groupBy(''col1''), ''a'')->count(''a.*'');
La solución de @JarekTkaczyk es exactamente lo que estaba buscando. Lo único que echo de menos es cómo hacerlo cuando está utilizando consultas DB::table()
. En este caso, así es como lo hago:
$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();
mergeBindings
especial sobre cómo hacer mergeBindings
sin usar el método getQuery()
Me gusta hacer algo como esto:
Message::select(''*'')
->from(DB::raw("( SELECT * FROM `messages`
WHERE `to_id` = ".Auth::id()." AND `isseen` = 0
GROUP BY `from_id` asc) as `sub`"))
->count();
No es muy elegante, pero es simple.
No pude hacer tu código para hacer la consulta deseada, el AS es un alias solo para la tabla abc
, no para la tabla derivada. Laravel Query Builder no admite implícitamente alias de tablas derivadas, DB :: raw es muy probablemente necesario para esto.
La solución más directa que pude encontrar es casi idéntica a la suya, sin embargo, produce la consulta como usted solicitó:
$sql = Abc::groupBy(''col1'')->toSql();
$count = DB::table(DB::raw("($sql) AS a"))->count();
La consulta producida es
select count(*) as aggregate from (select * from `abc` group by `col1`) AS a;