Convert this SQL query to Laravel? - mysql

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();

Related

Join Multiple Columns on Laravel Query Builder

I have no idea how to write it in Laravel Query Builder. Here's the SQL query:
select l.id, l.title, is1.similarity
FROM l
left join is1 on (l.id = is1.listing_id1 and is1.listing_id2 = 225678) or (l.id = is1.listing_id2 and is1.listing_id1 = 225678)
If I simply translate your SQL query to Laravel Query Builder query It would look like this.
DB::table('l')->select('l.id', 'l.title', 'is1.similarity')
->leftJoin('is1', function ($leftJoin) {
$leftJoin->on('l.id', '=', 'is1.listing_id1')->where('is1.listing_id2', '=', '225678')
->orOn('l.id','=', 'is1.listing_id2')->where('is1.listing_id1','=', '225678'); })
->get();
I guess, it would be something like this:
DB::table('l')
->('l.id', 'l.title', 'is1.similarity')
->join('is1', function ($join) {
$join->on('l.id', '=', 'is1.listing_id1') ->where('is1.listing_id2', '=', '225678')
->orOn('l.id','=', 'is1.listing_id2')->where('is1.listing_id1', '=', '225678');
})->get();
Don't forget to import this:
use Illuminate\Support\Facades\DB;
More information can be find here.

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.

Convert Raw SQL query to Laravel DB Query

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();

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');

mysql join ON and AND to laravel eloquent

I've been able to get the query result I need using the following raw sql:
select `person`.`id`, `full_name`, count(actions.user_id) as total
from `persons`
left join `actions`
on `actions`.`person_id` = `persons`.`id`
and `actions`.`user_id` = $user
where `type` = 'mp'
group by `persons`.`id`
But I haven't been able to get it working in eloquent yet.
Based on some similar answers, I'd tried functions within ->where() or leftJoin(), but the count of each person's actions isn't yet being filtered by $user. As it stands:
$query = Person::leftJoin('actions', function($q) use ($user)
{
$q->on('actions.person_id', 'persons.id')
->where('actions.user_id', $user);
})
->groupBy('persons.id')
->where('type', 'foo')
//->where('actions.user_id', '=', $user)
->get(['persons.id', 'full_name', DB::raw('count(actions.id) as total')]);
I'm at least heading in roughly the right direction, right...?
If it's relevant, the Persons.php model has two actions relationships:
public function actions()
{
return $this->hasMany('Action');
}
public function actionsUser($id)
{
return $this->hasMany('Action')->where('user_id', $id);
}
So, for reference, I solved it like so:
$query = Person::leftJoin('actions', function($q) use ($user)
{
$q->on('actions.person_id', '=', 'persons.id')
->where('actions.user_id', '=', "$user");
})
->groupBy('persons.id')
->where('type', 'foo')
->get(['persons.id', 'full_name', DB::raw('count(actions.id) as total')]);
The ->where() clause within leftJoin, oddly, needs the speech marks for the variable to be passed through the sql query correctly (likewise, '2' doesn't seem to work while "2" does).
I found that the where doesn't always work on the leftJoin clause
If in the future you get any trouble with it, I'd suggest you using this:
$query = Person::leftJoin('actions', function($q) use ($user)
{
$q->on('actions.person_id', '=', 'persons.id')
->on('actions.user_id', '=', "$user");
})
->groupBy('persons.id')
->where('type', 'foo')
->get(['persons.id', 'full_name', DB::raw('count(actions.id) as total')]);
Hope it helps someone.
When laravel eloquent just start getting complex like this
For more flexibility and readability I'll just use plain sql statement then hydrate the results.
$sql = "
SELECT `person`.`id`,
`full_name`,
count(actions.user_id) AS total
FROM `persons`
LEFT JOIN `actions`
ON `actions`.`person_id` = `persons`.`id`
AND `actions`.`user_id` = $user
WHERE `type` = 'mp'
GROUP by `persons`.`id`
";
$query = Person::hydrate(
DB::select( $sql )
);