Convert Raw SQL query to Laravel DB Query - mysql

I have the following raw SQL query:
select a.id user_id, a.email_address, a.name_first, a.name_last, count(b.id) number_of_videos, sum(b.vimeo_duration) total_duration, sum(b.count_watched) total_playbacks
from users a,
videos b
where a.id = b.tutor_id
and a.email_address in ('candace_rennie#yahoo.com', 'tjm#hiltoncollege.com', 'matthewjameshenshall#gmail.com', 'nkululeko#syafunda.co.za', 'khulile#syafunda.co.za', 'nzakheni#syafunda.co.za')
group by a.id;
This correctly gets 6 rows from the database. I'm trying to convert this to a Laravel database query like so:
$totals = DB::table('users')
->select(DB::Raw('users.id as user_id'), 'users.email_address', 'users.name_first', 'users.name_last', DB::Raw('count(videos.id) as number_of_videos'), DB::Raw('sum(videos.vimeo_duration) as total_duration'), DB::Raw('sum(videos.count_watched) as total_playbacks'))
->join('videos', 'users.id', '=', 'videos.tutor_id')
->where('users.id', 'videos.tutor_id')
->whereIn('users.email_address', array('candace_rennie#yahoo.com', 'tjm#hiltoncollege.com', 'matthewjameshenshall#gmail.com', 'nkululeko#syafunda.co.za', 'khulile#syafunda.co.za', 'nzakheni#syafunda.co.za'))
->groupBy('users.id')
->get();
This however return 0 rows. Is there anything I'm missing?

It should be smth like below even tho groupBy user id does not help much as id is unique.
$aggregates = [
DB::raw('count(b.id) as number_of_videos'),
DB::raw('sum(b.vimeo_duration) as total_duration'),
DB::raw('sum(b.count_watched) as total_playbacks'),
];
$simpleSelects = ['users.email_address', users.id, 'users.name_first', 'users.name_last'];
$emails = ['candace_rennie#yahoo.com', 'tjm#hiltoncollege.com'....]
$users = Users::select(array_merge($simpleSelects, $aggregates))
->leftJoin('videos as b', function ($join) use ($emails) {
$join->on('b.tutor_id', 'a.id')
->whereIn('users.email_address', $emails);
})
->groupBy('users.id')
->get();

Try to remove this line:
->where('users.id', 'videos.tutor_id')

List item
after sql code convert into laravel
DB::select('posts.id','posts.title','posts.body')
->from('posts')
->where('posts.author_id', '=', 1)
->orderBy('posts.published_at', 'DESC')
->limit(10)
->get();

Related

how to run mysql query in Laravel

I want to transform my MySql query into a Query in Laravel but I really don't know how to do this. I don't know how to rename in FROM like in SQL
My query is the following one :
SELECT f2.* FROM formation f2 WHERE f2.theme_id IN
(SELECT f.theme_id FROM user_formation uf JOIN formation f ON uf.formation_id = f.id WHERE uf.user_id = 2)
AND f2.id NOT IN
(SELECT formation_id FROM user_formation WHERE user_id = 2);
I tried something like this but ...
$q = Formation::query()
->from('formation AS f2')
->whereIn('f2.theme_id', function($r)
{
$r->select('f.theme_id')->from('user_formation AS uf')
->join('formation', function($join)
{
$join->on('uf.formation_id', '=', 'f.id')
->where ('uf.user_id', '=', $id)
});
});
->whereNotIn('f2.id', function($s){
$s->select('formation.id')
->from('user_formation')
->where('user_id', '=', $id)
})->get();
thanks for help.
If you want to run this raw query you can run:
$res = DB::select('
SELECT f2.*
FROM formation f2
WHERE f2.theme_id IN
(SELECT f.theme_id FROM user_formation uf JOIN formation f ON uf.formation_id = f.id WHERE uf.user_id = 2)
AND f2.id NOT IN
(SELECT formation_id FROM user_formation WHERE user_id = 2)');
Or you can rewrite this query in laravel query builder Eloquent ORM:
Formations::query()
->whereIn('formations.theme_id', function($q){
$user_formations_table = (new UserFormation)->getTable();
$formation_table = (new Formation)->getTable();
$q->select('paper_type_id')
->from($user_formations_table)
->join($formation_table, "$user_formations_table.formation_id", '=', "$formation_table.id")
->where("$user_formations_table.user_id", 2);
})->whereNotIn('formations.id', function($q){
$user_formations_table = (new UserFormation)->getTable();
$q->select('formation_id')
->where("$user_formations_table.user_id", 2);
})
->get();
Note that I have used models Formations, UserFormation, Formation Because you have used 3 different tables, you should add this models and specify tables to run ORM query
I advice to run first RAW query if there is no another need to run it with Eloquent
Hope this helps you
First of all, you need to fix your code indentations so you don't confuse yourself. Second, you placed semicolon in the wrong places. Third, you need to pass $id inside function because of the variable scope.
$q = Formation::query()
->whereIn('f2.theme_id', function($r) use ($id) {
$r->select('f.theme_id')->from('user_formation AS uf')
->join('formation', function($join) use ($id) {
$join->on('uf.formation_id', '=', 'f.id')
->where('uf.user_id', '=', $id);
}
);
})
->whereNotIn('f2.id', function($s) use ($id) {
$s->select('formation.id')
->from('user_formation')
->where('user_id', '=', $id);
})->get();
Note : If you are using VSCode, I suggest to use PHP Intelephense as it will help with autocomplete, syntax check, etc.

Join 3 table with query builder in laravel

I have a 3 table questions,registrations,ssi_tracks i need to get details from the registraions table by corresponding to other two tables
i need to get details from registrations based on
questions.question_schedul=0 ,ssi_tracks.track_first_status
i have wrote query but it says the column is not found here is my query
$register = DB::table('registrations')
->join('questions', 'registrations.registration_id', '=', 'questions.question_id')
->join('ssi_tracks','registrations.registration_id','=','ssi_tracks.registration_id')
->select('address', 'model', 'chassis', 'delivery_date','ssi_tracks.track_first_status')
->where([["questions.question_schedul", "=", $dropselected] and ['ssi_tracks.track_first_status',0]])
->get();
Try this:
$register = DB::table('registrations as R')
->select('R.address', 'R.model', 'R.chassis', 'R.delivery_date','S.track_first_status')
->join('questions as Q', 'R.registration_id', '=', 'Q.question_id')
->join('ssi_tracks as S','R.registration_id','=','S.registration_id')
->where('Q.question_schedul', '=', $dropselected)
->where('S.track_first_status', '=', 0)
->get();
Make sure you have used the right column here from question table for matching registration id:
->join('questions as Q', 'R.registration_id', '=', 'Q.question_id')
try this query :
$register = DB::table('registrations')
->leftJoin('questions', 'registrations.registration_id', '=', 'questions.question_id')
->leftJoin('ssi_tracks','registrations.registration_id','=','ssi_tracks.registration_id')
->select('registrations.address', 'registrations.model', 'registrations.chassis', 'registrations.delivery_date','ssi_tracks.track_first_status')
->where(['questions.question_schedul'=>$dropselected,'ssi_tracks.track_first_status'=>0])
->get();

Join ON AND with laravel eloquent query builder

I am trying to write the following sql query in laravel:
select
`workers`.`first_name`,
`workers`.`last_name`,
`occupations`.`approval_date`,
`occupations`.`certification_date`,
`occupations`.`expiration_date`,
`occupations`.`type`,
`workers`.`photo`
from `worker_print_queue`
inner join `workers` on `worker_print_queue`.`worker_id` = `workers`.`id`
inner join `occupations` on `worker_print_queue`.`certification` = `occupations`.`type` AND `workers`.`id` = `occupations`.`worker_id`
I have written it in eloquent in the following manner:
$records = \DB::table('worker_print_queue')
->join('workers', 'worker_print_queue.worker_id', '=', 'workers.id')
->join('occupations', function($join){
$join->on('workers.id', '=', 'occupations.worker_id')
->where('worker_print_queue.certification', '=', 'occupations.type');
})
->select('workers.first_name', 'workers.last_name', 'occupations.approval_date',
'occupations.certification_date', 'occupations.expiration_date', 'occupations.type', 'workers.photo')
->get();
But I am receiving no results. I'm sure there is something I'm missing, just not sure what it is.
The issue is that this line
->where('worker_print_queue.certification', '=', 'occupations.type');
is comparing the column 'worker_print_queue.certification' to the value 'occupations.type'.
If you change it to use the on clause you should be fine:
->on('worker_print_queue.certification', '=', 'occupations.type');

WhereNotIn Subquery

What i'm trying to achieve is the following:
I want to check if there is a record with the same client_code but with a lower/different campaign id. I'm using a sub-query for now and i tried to do it with a join as well but I couldn't get the logic working
This is what i got now:
$oDB = DB::table('campaigns AS c')
->select(
'c.id AS campaign_id',
'cc.id AS campaign_customer_id'
)
->join('campaign_customers AS cc', 'cc.campaign_id', '=', 'c.id')
->where('c.status', '=', ModelCampaign::STATUS_PLANNED)
->where('c.scheduled', '=', 1)
->whereRaw('c.scheduled_at <= NOW()')
->where('cc.status', '=', ModelCampaignCustomer::STATUS_INVITE_EMAIL_SCHEDULED)
->whereNotIn('cc.client_code', '=', function ($query){
$query ->select(DB::raw(1))
->from('campaign_customers')
->whereRaw('campaign_id', '!=', 'c.id');
})
->where('cc.active', '=', 1)
;
any tips on how to work the logic would be great
You can use the ->toSql(); method to see the SQL so you can refactorize your query.
The whereNotIn probably shouldn't have an = in it
->whereNotIn('cc.client_code', function ($query){
....
edit
Try:
->whereNotIn('cc.client_code', function ($query){
$query->select(DB::raw('client_code'))
->from('campaign_customers')
->whereRaw('campaign_id != c.id');
})
I think the whereRaw should be a single text string or maybe you can use where here (looking at this for reference https://laravel.com/docs/5.2/queries#advanced-where-clauses). Also DB::raw(1) is going to return a 1 for each subquery result but you want an id for the whereNotIn.

Convert this SQL query to Laravel?

Hi i have troubles converting this query to Laravel, my query works fine, but idk how to convert to a laravel query:
select p.id, p.enunciado, p.created_at, c.categoria, s.categoria
from preguntas_seleccion p, categorias c,sub_categorias s
where p.categorias_id = c.id and p.sub_categorias_id = s.id and c.id = s.categorias_id
Do you really need the last condition? Anyway, it should work like this (untested code!):
$query = \DB::table('preguntas_seleccion as p')->select("p.id","p.enunciado","p.created_at", "c.categoria","s.categoria");
$query->join('categorias', function($join)
{
$join->on('p.categorias_id', '=', 'c.id');
$join->on('c.id', '=', "s.categorias_id");
});
$query->join('sub_categorias as s', 'p.sub_categorias_id', '=', 's.id');
return $query->get();