Mysql query like this :
SELECT a.id, a.name, b.TotalMeal, c.TotalCollection
FROM users a
LEFT JOIN (
SELECT user_id, SUM( breakfast + dinner + lanch ) AS TotalMeal
FROM meals
GROUP BY user_id) b ON a.id = b.user_id
LEFT JOIN (
SELECT user_id, SUM( amount ) AS TotalCollection
FROM collections
GROUP BY user_id) c ON a.id = c.user_id
LIMIT 0, 30
I want to convert it to Laravel eloquent, but I'm confused. I have Three tables. eg - users( id, name,email ..), meals( user_id, breakfast,lanch,dinner) and collections(user_id, amount) .
There is a little hack that uses withCount() to select sums of related tables which can be used in your scenario:
User::query()
->select([
'id',
'name',
])
->withCount([
'meals as total_meals' => function ($query) {
$query->select(DB::raw('SUM(breakfast + dinner + lunch)'));
},
'collections as total_collections' => function ($query) {
$query->select(DB::raw('SUM(amount)'));
},
])
->get();
In this query, withCount will perform the joins for you.
Related
How to make with laravel a query with with like the example below
Thank you
with s as (select s.id from s)
select a.*
from a
left join s on s.id = a.s_id
...
WITH clauses are not supported by Eloquent. You can either pass in a raw query
$sql = <<<SQL
with s as (select s.id from s)
select a.*
from a
left join s on s.id = a.s_id
...
SQL;
$results = DB::select($sql);
Or use a package that adds this functionality like staudenmeir/laravel-cte
DB::query()
->withExpression('s', fn ($query) => $query->select('s.id')->from('s'))
->select('a.*')
->from('a')
->leftJoin('s', 's.id', 'a.s_id')
...
$users = SELECT users.id,
users.name,
cd.title,
cd.updated_at,
profiles.avatar
FROM `users`
JOIN (SELECT Max(id) max_id,
user_id
FROM book
GROUP BY user_id) c_max
ON ( c_max.user_id = users.id )
JOIN book cd
ON ( cd.id = c_max.user_id )
JOIN profiles
ON ( profiles.user_id = users.id )
ORDER BY cd.updated_at DESC
i am using this to get data in laravel query
$users = DB::select(DB::raw('SELECT users.id, users.name, cd.title, cd.updated_at, profiles.avatar FROM users JOIN ( SELECT MAX(id) max_id, user_id FROM book GROUP BY user_id )
c_max ON (c_max.user_id = users.id) JOIN book cd ON (cd.id = c_max.user_id) JOIN profiles ON (profiles.user_id = users.id) ORDER by cd.updated_at DESC limit 24 offset 0'));
How can I do this in Laravel ORM?
SELECT
s.id,
s.name AS NAME,
COALESCE(su.cnt, 0) AS SUBJECTs,
COALESCE(e.marks, 0) AS MARKS
FROM student s
LEFT JOIN
(
SELECT student_id, COUNT(*) AS cnt
FROM subject
GROUP BY student_id
) su
ON s.id = su.student_id
LEFT JOIN
(
SELECT student_id, SUM(mark) AS marks
FROM exam
GROUP BY student_id
) e
ON s.id = e.student_id;
I want to join between STUDENT and SUBJECT, STUDENT and EXAM. The problem is happening when I join the third table, it duplicates the results.
This is
DB::table('student as su')->selectRaw("
su.id,
su.name,
COALESCE(su.cnt, 0) as SUBJECTS,
COALESCE(e.marks, 0) as MARKS
")->leftJoin(DB::raw("(
SELECT student_id, COUNT(*) AS cnt
FROM subject
GROUP BY student_id
) su"), 's.id', '=', 'su.student_id')
->leftJoin(DB::raw("(
SELECT student_id, SUM(mark) AS marks
FROM exam
GROUP BY student_id
) e"), 's.id', '=', 'e.student_id')
How to do the following with laravel ORM?
select f.type, f.variety, f.price
from (
select type, min(price) as minprice
from fruits group by type
) as x inner join fruits as f on f.type = x.type and f.price = x.minprice;
$subQuery = "(select type, min(price) as minprice from fruits group by type) as x";
$query = DB::table('fruits')::selectRaw( "fruits.type,fruits.variety,x.minprice" );
$query->join( DB::raw($subQuery), function ($join) {
$join->on ( 'fruits.type', '=', 'x.type' );
});
$data = $query->get();
I have not tested the code but hopes it works.
I want to join on a result of other select like this :
SELECT *
FROM TABLE1
JOIN (
SELECT cat_id FROM TABLE2 where brand_id = 2 GROUP BY TABLE2.cat_id) AS b ON TABLE1.id = b.cat_id
is there any way to do this with eloquent?
As it is mentioned here, using DB:raw() will solve your problem.
DB::table('table1')->join(DB::raw("(SELECT
cat_id
FROM table2
WHERE brand_id = 2
GROUP BY table2.cat_id
) as b"),function($join){
$join->on("b.cat_id","=","table1.id");
})->get();
\DB::table('table1')->join('table2' , function($join){
$join->on('table1.id', '=', 'table2.cat_id');
})->select(['table2.cat_id' , 'table1.*'])
->where('table2.brand_id' , '=' , '2')
->groupBy('table2.cat_id');
Depends on whether brand_id is in table1 or table2
You can also use model approach for it.
TABLE1::join('table2' , function($join){
$join->on('table1.id', '=', 'table2.cat_id');
})->select(['table2.cat_id' , 'table1.*'])
->where('table2.brand_id' , '=' , '2')
->groupBy('table2.cat_id');