laravel execute subquery query and get count - laravel

how select query like this in Laravel -
Select t.*, count(Select * from persons person
where person.user_id = t.id) from users t

try:
DB::table('users')
->selectRaw('*, count(SELECT * FROM persons WHERE persons.user_id = users.id)')
->get();

In my opinion to count data of other table, you can use join table combining with group. It's same as your query. You can do this:
$users = DB::table('users')
->join('persons', 'users.id', '=', 'persons.user_id')
->select('users.*', count(persons.user_id))
->groupBy('persons.user_id')
->get();
I hope this can help you.

Related

how to join query different table in laravel

I try to join three tables which are named attendances, categories, and users.
my code is
$Attendance= DB::table('users')
->join('categories','users.U_category_id', '=', 'categories.id')
->select('users.*','categories.batch_name')->get();
but I also need to join attendances table where attendances column User_A_ID and users table id are the same. How can I do this?
You can try it with
$Attendance= DB::table('users')
->join('categories','users.U_category_id', '=', 'categories.id')
->join('attendances','users.id', '=', 'attendances.User_A_ID')
->select('users.*','categories.batch_name')->get();

I want to pass this query to Eloquent in laravel

I'm trying to make a query with eloquent, I try to get all the users who have one or more ads, taking into account that it is a one to many relationship (users to ads).
This query in general does what I want, but I do not know if it is well done and also how to pass it to Eloquent through the User model.
SELECT users.id, COUNT( anuncio.id ) AS 'total' FROM users
INNER JOIN anuncio ON users.id = anuncio.usuario_id WHERE
(SELECT COUNT( * ) FROM anuncio WHERE anuncio.usuario_id = users.id) >0
GROUP BY users.id ORDER BY total DESC
I have tried several ways that only return Builder to me.
For example:
$listas = new User;
$listas = $listas->join('anuncio','users.id','=','anuncio.usuario_id');
$listas = $listas->select(array('users.*', DB::raw('COUNT(anuncio.id) AS total')));
$listas = $listas->where(function($query) use ($listas){
$query->select(DB::raw('COUNT(anuncio.usuario_id)'))
->where('anuncio.usuario_id','=','users.id')
->groupBy('anuncio.usuario_id');
},'>','0');
$listas = $listas->orderBy('total','DESC')->paginate(48);
By any suggestion I will be very grateful.
Try with this
$listas = User::join('anuncio','users.id','=', 'anuncio.usuario_id')
->select('users.id',DB::raw("count(anuncio.id) as total"))
->groupby('users.id')
->having('total', '>', '0')
->orderby('total', 'desc')
->get();
Just use left join for this.
$users = DB::table('users')
->leftJoin('anuncio', 'users.id', '=', 'anuncio.usuario_id')
->get();
So Left Join will only select those result which has any match in anuncio table.

Laravel: change a raw query in a "query-builder" or "eloquent" one

I have this Laravel Query Builder snippet that is working fine:
$records = DB::table('users')
->select(
DB::raw('users.*, activations.id AS activation,
(SELECT roles.name FROM roles
INNER JOIN role_users
ON roles.id = role_users.role_id
WHERE users.id = role_users.user_id LIMIT 1)
AS role')
)
->leftJoin('activations', 'users.id', '=', 'activations.user_id')
->where('users.id', '<>', 1)
->orderBy('last_name')
->orderBy('first_name')
->paginate(10);
Is there a way to avoid use of raw queries and get the same result? In other words, how can I write this in a more "query-builder" style? Can I also translate this into an Eloquent query?
Thanks
You can used selectSub method for your query.
(1) First create the role query
$role = DB::table('roles')
->select('roles.name')
->join('roles_users', 'roles.id', '=', 'role_users.role_id')
->whereRaw('users.id = role_users.user_id')
->take(1);
(2) Second added the $role sub query as role
DB::table('users')
->select('users.*', 'activations.id AS activation')
->selectSub($role, 'role') // Role Sub Query As role
->leftJoin('activations', 'users.id', '=', 'activations.user_id')
->where('users.id', '<>', 1)
->orderBy('last_name')
->orderBy('first_name')
->paginate(10);
Output SQL Syntax
"select `users`.*, `activations`.`id` as `activation`,
(select `roles`.`name` from `roles` inner join `roles_users` on `roles`.`id` = `role_users`.`role_id`
where users.id = role_users.user_id limit 1) as `role`
from `users`
left join `activations` on `users`.`id` = `activations`.`user_id`
where `users`.`id` <> ?
order by `last_name` asc, `first_name` asc
limit 10 offset 0"

subquery with distinct clause in query builder/laravel

SELECT * FROM `movie_list`
WHERE `movie_id` IN
(SELECT DISTINCT movie_id FROM `movie_genre` where genre_id in (12,18,53))
AND rated IN
('Not Rated','N/A')
How can i convert the above to a query builder syntax:
$movies = DB::table('movie_list')
->whereIn('movie_id',function($query){
$query->select.....
})->get();
I have the inner one: it goes like this:
DB::table('movie_genre')
->whereIn('genre_id', array(12,18,53))
->distinct()
->get(array('movie_id'));
How do i use this result with the rest of my query?
You could do this alot smoother with Eloquent Models, but assuming you don't have your models setup, this should do the trick (untested)
$ids = DB::table('movie_genre')
->whereIn('genre_id', [12,18,33])
->distinct()
->get(['movie_id'])
->toArray();
$movies = DB::table('movie_list')
->whereIn('movie_id', array_values($ids))
->get();

Laravel ordering results of a left join

I am trying to replicate the below SQL in Laravels Eloquent query builder.
select a.name, b.note from projects a
left join (select note, project_id from projectnotes order by created_at desc) as b on (b.project_id = a.id)
where projectphase_id = 10 group by a.id;
So far I have:
$projects = Project::leftjoin('projectnotes', function($join)
{
$join->on('projectnotes.project_id', '=', 'projects.id');
})
->where('projectphase_id', '=', '10')
->select(array('projects.*', 'projectnotes.note as note'))
->groupBy('projects.id')
->get()
which works for everything except getting the most recent projectnotes, it just returns the first one entered into the projectnotes table for each project.
I need to get the order by 'created_at' desc into the left join but I don't know how to achieve this.
Any help would be much appreciated.
Your subquery is unnecessary and is just making the entire thing inefficient. To be sure though, make sure this query returns the same results...
SELECT
projects.name,
notes.note
FROM
projects
LEFT JOIN
projectnotes notes on projects.id = notes.project_id
WHERE
projects.projectphase_id = 10
ORDER BY
notes.created_at desc
If it does, that query translated to the query builder looks like this...
$projects = DB::table('projects')
->select('projects.name', 'notes.note')
->join('projectnotes as notes', 'projects.id', '=', 'notes.project_id', 'left')
->where('projects.projectphase_id', '=', '10')
->orderBy('notes.created_at', 'desc')
->get();

Resources