Convert SQL to Eloquent to Join multiple table and Count - php

I have been this SQL working fine, but trying to convert it to Eloquent format, it keeps returning a wrong, SQL entirely which flags error.
Coding with Laravel 5.5
Select arm_articles.article_topic, arm_articles.id, arm_articles.article_id,
COUNT(arm_article_views.view_article_id) AS TotalViews,
COUNT( arm_article_likes.liked_article_id) AS TotalLikes,
COUNT( arm_article_comments.comment_article_id) AS TotalComments
FROM arm_articles
LEFT JOIN arm_article_views ON arm_articles.article_id = arm_article_views.view_article_id
LEFT JOIN arm_article_likes ON arm_articles.article_id = arm_article_likes.liked_article_id
LEFT JOIN arm_article_comments ON arm_articles.article_id = arm_article_comments.comment_article_id
GROUP BY arm_articles.article_id
ORDER BY TotalLikes, TotalLikes, TotalComments ASC`
HOW I MADE ELOQUENT QUERY BUILDER Not working though:
return Datatables::of(PostModel::leftJoin('arm_article_views', 'arm_article_views.view_article_id', '=', 'arm_articles.article_id')
->leftJoin('arm_article_likes','arm_article_likes.liked_article_id', '=', 'arm_articles.article_id')
->leftJoin('arm_article_comments', 'arm_article_comments.comment_article_id','=','arm_articles.article_id')
->selectRaw(
'arm_articles.*,
count(arm_article_views.view_article_id) AS ViewCount'
)
->groupBy('arm_articles.article_id')->orderBy('ViewCount','DESC')
->where('arm_articles.article_contributor_id','=',$contributor_id)
->getQuery())->make(true);
Any hint would be appreciated

Try with this:
DB::table('arm_articles')
->leftJoin('arm_article_views', 'arm_articles.article_id', '=', 'arm_article_views.view_article_id')
->leftJoin('arm_article_likes', 'arm_articles.article_id', '=', 'arm_article_likes.liked_article_id')
->leftJoin('arm_article_comments', 'arm_articles.article_id', '=', 'arm_article_comments.comment_article_id')
->groupBy('arm_articles.article_id', 'article_topic')
->select(
DB::raw('count(arm_article_views.view_article_id) as TotalViews'),
DB::raw('count(arm_article_likes.liked_article_id) as TotalLikes'),
DB::raw('count(arm_article_comments.comment_article_id) as TotalComments'),
'arm_articles.article_id',
'article_topic'
)->get();

Related

raw query join left with select to laravel 8 query

i'm using raw query on my laravel function, and i wanna make it into laravel query builder, but i really have no idea how to do it, i've read laravel documentary about advanced join clause or subquery joins, but still cant figuring it out how to convert it
raw query :
$buku = DB::select(
DB::raw('
SELECT buku.*, kategory, tag
FROM buku
LEFT JOIN kategori_buku ON buku.id_kategori = kategori_buku.id
LEFT JOIN detail_buku_tag ON buku.id = detail_buku_tag.id_buku
LEFT JOIN (SELECT tag_buku.id, GROUP_CONCAT(tag) AS tag FROM tag_buku) AS tag_buku ON tag_buku.id = detail_buku_tag.id_tag
GROUP BY buku.id')
);
there some sql chaining issue. #Ramiz Kongulov forget to split group by clause try this.
$buku = \DB::table('buku')
->select(['buku.*','kategory.*', 'tag.*'])
->leftJoin('kategori_buku', 'kategori_buku.id', '=', 'buku.id_kategori')
->leftJoin('detail_buku_tag', 'detail_buku_tag.id_buku', '=', 'buku.id')
->leftJoin(\DB::raw('(SELECT tag_buku.id, GROUP_CONCAT(tag) AS tag FROM tag_buku) AS tag_buku'),
'tag_buku.id', '=', 'detail_buku_tag.id_tag')
->groupBy('buku.id')
->get();
try this
$buku = \DB::table('buku')
->select([
'buku.*',
'kategory.*',
'tag.*'
])
->leftJoin('kategori_buku', 'kategori_buku.id', '=', 'buku.id_kategori')
->leftJoin('detail_buku_tag', 'detail_buku_tag.id_buku', '=', 'buku.id')
->leftJoin(DB::raw('SELECT tag_buku.id, GROUP_CONCAT(tag) AS tag FROM tag_buku) AS tag_buku ON tag_buku.id = detail_buku_tag.id_tag GROUP BY buku.id'))
->get();

Laravel 7: getting rows between two dates where the column is datetime

I'm having trouble building an eloquent query wherein I can recreate this sql command:
The date_created column is datetime.
SELECT * FROM covidchecklist cc
LEFT JOIN patient_appointment pa ON cc.appointment_id = pa.appointment_id
LEFT JOIN users pat ON pa.user_id = pat.id
WHERE DATE_FORMAT(cc.date_created,'%Y-%m-%d') BETWEEN '2021-01-27' AND '2021-01-27'
What I have right now:
CovidChecklist::
leftJoin('patient_appointment', 'covidchecklist.appointment_id', '=', 'patient_appointment.appointment_id')
->leftJoin('users as patient', 'patient_appointment.user_id', '=', 'patient.id')
->whereRaw(' DATE_FORMAT(covidchecklist.date_created,"%Y-%m-%d") BETWEEN '.'$this->date_from'.' AND '.'$this->date_to'.' ')
->select(
*select stuff*
)
->get();
I am using whereRaw since I can't get this to work:
->whereBetween('covidchecklist.date_created', [$this->date_from, $this->date_to])
Try this, mate
->whereBetween(\DB::raw('DATE_FORMAT(covidchecklist.date_created,"%Y-%m-%d")'), [$this->date_from, $this->date_to])

Left join 2 times raw query laravel doesn't work (Laravel)

I tried my raw query sql in laravel and i need to left join it 2 times but the print out is wrong. It different from mysql. I've tried in mysql and it works well
this is my code :
$tabel = DB::SELECT(DB::RAW("
SELECT codeh.info_code kh_infocode, codep.no_code khp_nocode,
codep.info_code khp_infocode,
codep.name_code khp_namecode, t.* FROM transactions t
LEFT JOIN users u ON t.user_id=u.id
LEFT JOIN divisions d ON d.id=u.division_id
LEFT JOIN all_codes codep ON t.code_p_id=codep.id
LEFT JOIN all_codes codeh ON t.allcode_id=codeh.id
WHERE 1=1
AND d.id=$div_id
AND codep.no_code LIKE '$allcode->no_code%'
$db_date
ORDER BY t.date, khp_nocode
"));
it works really well in sql but when i put it in laravel kh_infocode change and the value same like khp_infocode even though kh_infocode has different value with khp_infocode
Everything is in the official docs. It's not even long, go give it a read.
DB::table('transactions as t')
->select(
'codeh.info_code',
'kh_infocode',
'codep.no_code',
'khp_nocode',
'codep.info_code',
'khp_infocode',
'codep.name_code',
'khp_namecode',
't.*',
)
->leftJoin('users as u', 't.user_id', '=', 'u.id')
->leftJoin('all_codes as codep', 't.code_p_id', '=', 'codep.id')
->leftJoin('all_codes as codeh', 't.allcode_id', '=', 'codeh.id')
->where('d.id', '=', $div_id)
->where('codep.no_code', 'like', $allcode->no_code.'%')
->orderBy('t.date')
->orderBy('khp_nocode')
->get();
simply set SQL string directly without DB::RAW()
$tabel = DB::SELECT('your select statment');

This row query working properly please help to change it eloquent query

SELECT `foduu_listing`.`id`,`foduu_listing_filedetail`.`primary`, `foduu_listing`.`name`,`foduu_listing`.`filemanager_id`,`foduu_filemanager`.`filepath`,`foduu_detail_orders`.`listing_id`, COUNT(`foduu_detail_orders`.`listing_id`) AS count,SUM(`foduu_detail_orders`.`total`) AS total
FROM foduu_listing
left join `foduu_detail_orders` on `foduu_listing`.`id` = `foduu_detail_orders`.`listing_id`
left join `foduu_listing_filedetail` on `foduu_listing`.`id` = `foduu_listing_filedetail`.`listing_id`
left join `foduu_filemanager` on `foduu_listing`.`filemanager_id` = `foduu_filemanager`.`id`
where `foduu_detail_orders`.`listing_id` = 593
I would do it like this:
DB::table('foduu_listing')->select('foduu_listing.id`,foduu_listing_filedetail.primary, foduu_listing.name,foduu_listing.filemanager_id,foduu_filemanager.filepath,foduu_detail_orders.listing_id')
->leftJoin('foduu_detail_orders', 'foduu_listing.id', '=', 'foduu_detail_orders.listing_id')
->leftJoin('foduu_listing_filedetail', 'foduu_listing.id', '=', 'foduu_listing_filedetail.listing_id')
->leftJoin('foduu_filemanager', 'foduu_listing.filemanager_id', '=', 'foduu_filemanager.id')
->selectRaw('COUNT(`foduu_detail_orders`.`listing_id`) AS count')
->selectRaw('SUM(`foduu_detail_orders`.`total`) AS total')
->where('foduu_detail_orders.listing_id', 593)
->get();
If instead of calling get at the end you call toSql you can check the query generated:
select `foduu_listing`.`id``,foduu_listing_filedetail`.`primary, foduu_listing`.`name,foduu_listing`.`filemanager_id,foduu_filemanager`.`filepath,foduu_detail_orders`.`listing_id`, COUNT(`foduu_detail_orders`.`listing_id`) AS count, SUM(`foduu_detail_orders`.`total`) AS total from `foduu_listing` left join `foduu_detail_orders` on `foduu_listing`.`id` = `foduu_detail_orders`.`listing_id` left join `foduu_listing_filedetail` on `foduu_listing`.`id` = `foduu_listing_filedetail`.`listing_id` left join `foduu_filemanager` on `foduu_listing`.`filemanager_id` = `foduu_filemanager`.`id` where `foduu_detail_orders`.`listing_id` = ?
However you are not making use of Laravel tools if you just translate your queries from raw SQL to Eloquent like this, you should define your models and your relationships properly and then make use of that for querying your data.

Different results using same query with DB::raw and Eloquent

I'm getting some unexpected results when running an Eloquent join query. I get two different results from using the exact same query. One running with DB::raw(), the second with Eloquent.
In the Eloquent query, the Users that matches the
where squad_user.leave_time >= seasons.start_time
are missing and will not be included in the result set. The users that matches the
or squad_user.leave is null
will be included, however.
That's the only difference in the results from the two queries. The raw query actually produces the desired result set.
What really puzzles me is, if I check the query logs, both Laravel's and MySQL, I get the exact same query when running both the raw and Eloquent query.
Raw query (the actual query i get from the query log when running the Eloquent query)
return \DB::select(\DB::raw('
select users.*
from users
inner join squad_user on users.id = squad_user.user_id
inner join seasons on squad_user.squad_id = seasons.squad_id
where squad_user.join_time <= seasons.end_time
and (squad_user.leave_time >= seasons.start_time or squad_user.leave_time is null)
and seasons.id = :seasonId
'),
['seasonId' => 3]
);
Eloquent query
return User::join('squad_user', 'users.id', '=', 'squad_user.user_id')
->join('seasons', 'squad_user.squad_id', '=', 'seasons.squad_id')
->where('squad_user.join_time', '<=', 'seasons.end_time')
->where(function ($query)
{
$query->where('squad_user.leave_time', '>=', 'seasons.start_time')
->orWhereNull('squad_user.leave_time');
})
->where('seasons.id', 3)
->get(['users.*']);
Laravel's Eloquent query log
select `users`.*
from `users`
inner join `squad_user` on `users`.`id` = `squad_user`.`user_id`
inner join `seasons` on `squad_user`.`squad_id` = `seasons`.`squad_id`
where `squad_user`.`join_time` <= seasons.end_time
and (`squad_user`.`leave_time` >= seasons.start_time or `squad_user`.`leave_time` is null)
and `seasons`.`id` = 3
{"bindings":["seasons.end_time","seasons.start_time",3],"time":0.38,"name":"mysql"}
MySQL's general_log on the Eloquent query
select `users`.*
from `users`
inner join `squad_user` on `users`.`id` = `squad_user`.`user_id`
inner join `seasons` on `squad_user`.`squad_id` = `seasons`.`squad_id`
where `squad_user`.`join_time` <= ?
and (`squad_user`.`leave_time` >= ? or `squad_user`.`leave_time` is null)
and `seasons`.`id` = ?
MySQL's general_log on the Raw query
select users.*
from users
inner join squad_user on users.id = squad_user.user_id
inner join seasons on squad_user.squad_id = seasons.squad_id
where squad_user.join_time <= seasons.end_time
and (squad_user.leave_time >= seasons.start_time or squad_user.leave_time is null)
and seasons.id = ?
I would appreciate any pointers here, as I am very lost.
where binds 3rd param and treats it usually as a string, unless you tell it not to by using raw statement. DB::raw or whereRaw will work for you:
return User::join('squad_user', 'users.id', '=', 'squad_user.user_id')
->join('seasons', 'squad_user.squad_id', '=', 'seasons.squad_id')
->where('squad_user.join_time', '<=', DB::raw('seasons.end_time'))
->where(function ($query)
{
$query->where('squad_user.leave_time', '>=', DB::raw('seasons.start_time'))
->orWhereNull('squad_user.leave_time');
})
->where('seasons.id', 3)
->get(['users.*']);
Since Laravel Verion 5.2 you can also use whereColumn to verify that two columns are equal (or pass a comparison operator to the method):
->whereColumn('squad_user.join_time', '<=', 'seasons.end_time')

Categories