Converting simple nested select query to Laravel's Eloquent query - php

i am having this query with me which needs to be written in the eloquent form on internet not able to find exact solution for my problem.
SELECT
query_id, t1.time, result, platform_id
FROM
query_logs t1
WHERE
t1.time = (SELECT
MAX(time)
FROM
query_logs t2
WHERE
t1.query_id = t2.query_id);
i tried writing it as below i used query_Logs as model to my controller:
$bmdata = Query_Logs::select('query_id', 'time','result','platform_id')
->where('time', function($q){
$q->from('query_logs')
->selectRaw('max(time)')
->where('query_id', '=', 'query_id')
})
->get();
Can you guys help me with the same.

Use this:
$bmdata = Query_Logs::select('query_id', 'time', 'result', 'platform_id')
->where('time', function($q) {
$q->from('query_logs as t2')
->selectRaw('max(time)')
->whereColumn('t2.query_id', '=', 'query_logs.query_id');
})->get();

Related

Create subquery in NOT IN

I am using Laravel Framework 6.16.0.
I have the following sql query:
SELECT DISTINCT
`companies`.*
FROM
`companies`
LEFT JOIN `trx` ON `trx`.`companies_id` = `companies`.`id`
WHERE
`trx`.`transaction_date` >= 2020-11-12 AND companies.symbol NOT IN (SELECT DISTINCT
companies.symbol
FROM
`companies`
LEFT JOIN articles a ON a.companies_id = companies.id
WHERE
a.created_at >= 2020-11-12
ORDER BY
created_at
DESC)
ORDER BY
transaction_date
DESC
I have created the following eloquent query:
DB::connection('mysql_prod')->table('companies')->select('companies.symbol')
->leftJoin('trx', 'trx.companies_id', '=', 'companies.id')
->where('trx.transaction_date', '>=', Carbon::today()->subDays(1)->startOfDay())
->orderBy('transaction_date', 'desc')
->distinct()
->get('symbol');
However, I am not sure how to pack the in my eloquent query to get all the symbol back that should be excluded.
I highly appreciate your replies!
You should try something like this:
$date = Carbon::today()->subDays(1)->startOfDay();
DB::connection('mysql_prod')->table('companies')->select('companies.symbol')
->leftJoin('trx', 'trx.companies_id', '=', 'companies.id')
->where('trx.transaction_date', '>=', $date)
->whereNotIn('companies.symbol', function ($q) use ($date) => {
$q->select('companies.symbol')
->from('companies')
->leftJoin('articles', 'articles.companies_id', 'companies.id')
->where('articles.created_at', '>', $date)
->distinct()
->get()
})
->orderBy('transaction_date', 'desc')
->distinct()
->get();
It will provide a similar query as you mentioned.
Reference from here.
Also, you can read how to write sub Query from Laravel docs.
Check this one more good answer for that what you need.

Helpe me to convert SQL query to Laravel eloquent

I have this SQL query:
SELECT *, count(*) as mostView FROM users RIGHT JOIN visitors ON users.id = visitors.user_id GROUP BY users.id HAVING users.isActive=1 AND users.fullName IS NOT NULL AND users.photo_id IS NOT NULL AND users.role_id IN(1, 3) ORDER BY mostView DESC LIMIT 5
It works, but I need convert to Laravel eloquent, i'm using laravel 5.6, could any one helpe me thanks in advance
I'm assuming that you have map the relationship in your Model if you do you can do like below,
$userViews = User::->with('vistors')
->where('isActive',1)
->whereNotNull('fullName')
->whereNotNull('photo_id')
->whereIn('role_id ',[1,3])
->get();
$mostView = $userViews->sortBy(function ($collection) {
return $collection->vistors->count()
})->take(5)
hope this helps
Not going to spoon feeding but can provide you some ideas to convert raw sql to eloquent, your sql should ideally be like this:
User::selectRaw('*', 'count(*) as mostView')
->rightJoin()
->groupBy()
->having()
->where // whereNotNull // wherIn
->orderBy()
->take(5)
->get();
Kindly refer to laravel docs: https://laravel.com/docs/5.6/queries
Thanks for all i'm studies Database: Query Builder on the link
https://laravel.com/docs/5.6/queries
and so i solved my question by myself
the answer is:
$mostViews = DB::table('users')
->rightJoin('visitors', 'users.id' , '=' , 'visitors.user_id')
->select('users.*', DB::raw('count(*) as mostView'))
->where('isActive', '=', '1')
->whereNotNull('fullName')
->where('photo_id', '<>', 'NULL')
->where(function ($q){
$q->where('role_id', '=', '1')
->orWhere('role_id', '=', '3');
})
->groupBy('user_id')
->orderBy('mostView', 'desc')->take(5)->get();

Laravel: MYSQL query in laravel

I have a working query goes like this
SELECT s.name as status, q.name as quality, p.name process, count(*)
FROM plates
JOIN equipment_status_codes s on equipment_status_code_id = s.id
JOIN plate_qualities q on plate_quality_id = q.id
JOIN processes p on process_id = p.id WHERE project_id in
(SELECT id
from projects
WHERE name like 'SPIRIT')
GROUP BY s.name, q.name, p.name ASC with ROLLUP
This works just and returns results just fine.
Now I am trying to put this in laravel syntax, but having some difficulties.
So I was thinking something along these lines.
return Plate::select('equipment_status_codes.name as Status', 'plate_qualities.name as Quality', 'processes.name as Process')
->join('equipment_status_codes', 'plates.equipment_status_code_id', '=', 'equipment_status_codes.id')
->join('plate_qualities', 'plates.plate_quality_id', '=', 'plate_qualities.id')
->join('processes', 'plates.process_id', '=', 'processes.id')
->groupBy(DB::raw('equipment_status_code_id WITH ROLLUP'))
...
...
->get();
Would someone help out. Thanks in advance!
Update:
#Govind Samrow
I have tried this query. It works (with couple of small adjustment) But I am not getting the same results as the one I get when I run the sql query.
I included screen shots.
So when I run the sql query.
I get the following results.
When I run the laravel query.
return DB::table('plates')
->join('equipment_status_codes', 'equipment_status_code_id', '=', 'equipment_status_codes.id')
->join('plate_qualities', 'plate_quality_id', '=', 'plate_qualities.id')
->join('processes', 'process_id', '=', 'processes.id')
->whereRaw("project_id IN(SELECT id from projects WHERE name like 'SPIRIT')")
->select(DB::raw('equipment_status_codes.name as Status'), DB::raw('IFNULL(plate_qualities.name, NULL) as Quality'), DB::raw('IFNULL(processes.name, NULL) as process'), DB::raw("COUNT(*) as Total" ))
->groupBy(DB::raw('equipment_status_codes.name WITH ROLLUP', 'plate_qualities.name WITH ROLLUP', 'processes.name WITH ROLLUP', 'asc'))
->get();
I get the following.
Almost there, but I am not sure what's going on?! Any ideas?
Try following Query for Joining with where Condition
return Plate::select('equipment_status_codes.name as Status', 'plate_qualities.name as Quality', 'processes.name as Process')
->join('equipment_status_codes', 'plates.equipment_status_code_id', '=', 'equipment_status_codes.id')
->join('plate_qualities', 'plates.plate_quality_id', '=', 'plate_qualities.id')
->join('processes', function($join)
{
$join->on('plates.process_id', '=', 'processes.id')
->whereIn('project_id', DB::table('projects')->where('name','LIKE','SPIRIT')->select('id')->get()->toArray());
})
->groupBy(DB::raw('equipment_status_code_id WITH ROLLUP'))
->get();
Hope this will help.
Use whereRaw for sub query in where clause Try this:
DB::table('plates')
->join('equipment_status_codes', 'equipment_status_code_id', '=', 'equipment_status_codes.id')
->join('plate_qualities', 'plate_quality_id', '=', 'plate_qualities.id')
->join('processes', 'process_id', '=', 'processes.id')
->whereRaw("project_id IN(SELECT id from projects WHERE name like 'SPIRIT')")
->select('equipment_status_codes.name as status', 'plate_qualities.name as quality', 'q.name as quality', 'processes.name as Process', DB::raw("COUNT(*) as Total"))
->groupBy(DB::raw('equipment_status_codes.name, plate_qualities.name, processes.name ASC with ROLLUP'))->get();
Here is raw sql result of above that got with toSql():
select `equipment_status_codes`.`name` as `status`, `plate_qualities`.`name` as `quality`, `q`.`name` as `quality`,
`processes`.`name` as `Process`, COUNT(*) as Total from `plates`
inner join `equipment_status_codes` on `equipment_status_code_id` = `equipment_status_codes`.`id`
inner join `plate_qualities` on `plate_quality_id` = `plate_qualities`.`id`
inner join `processes` on `process_id` = `processes`.`id`
where project_id IN(SELECT id from projects WHERE name like 'SPIRIT')
group by equipment_status_codes.name, plate_qualities.name, processes.name ASC with ROLLUP
Note: You can use SQL output with $query->toSql() and then compare with your actual SQL query.
You may use the table method on the DB facade to begin a query. The table method returns a fluent query builder instance for the given table, allowing you to chain more constraints onto the query and then finally get the results using the get method:
Check its link and get knowladge for laravel query builder:-
https://laravel.com/docs/5.4/queries

MySQL query to Laravel Eloquent

I have the following MySQL query:
SELECT
*
FROM
news_posts
WHERE
user_id = ?
AND id NOT IN (SELECT
post_id
FROM
user_read
WHERE
user_id = ?)
I want to make it more "eloquent". I've tried the following, but its (obviously) not working:
NewsPost::where('user_id', Auth::id())
->whereNotIn(function ($query) {
$query->DB::table('user_read')
->select('post_id')
->where('user_id', Auth::id());
})->get();
I'm assuming the 'where' method is executing a simple SQL query on 'new_posts' table. Can you try to rewrite this query and let mysql do the filtering for new posts? (search for LEFT OUTER JOIN on mysql)
SELECT *
FROM news_posts a
JOIN user_read b
ON a.id = b.post_id
WHERE a.user_id = ?
AND b.post_id IS NULL;
Thanks for all the replies! Got it working with the following tweaks:
NewsPost::where('user_id', Auth::id())
->whereNotIn('id', function ($query) {
$query->select('post_id')
->from('user_read')
->where('user_id', Auth::id());
})
->get();

Convert mysql query into Eloquent laravel query

I am trying to make the following query in laravel:
SELECT a.name AS subname, a.area_id, b.name, u. id, u.lawyer_id,u.active_search,
FROM subarea a
LEFT JOIN user_subarea u ON u.subarea_id = a.id
AND u.user_id = ?
LEFT JOIN branch b ON a.area_id = b.id
The idea is to obtain the subareas and see if the search is activated by the user.
The user_subarea table might have a record that matches the id of the subarea table where the active_search is equal to 0 or 1. If it doesn't exist I would like the query to return null.
While I was able to achieve this in raw SQL when I try the same with eloquent in Laravel I am not returning any value. I have done the following:
$query = DB::table('subarea')
->join('user_subarea', function($join)
{
$value = \Auth::user()->id;
$join->on( 'subarea.id', '=', 'user_subarea.subarea_id')->where('user_subarea.user_id', '=',$value);
})
->leftJoin('branch', 'subarea.area_id', '=', 'branch.id')
->select('branch.name', 'subarea.name as subarea', 'user_subarea.active_search_lawyer', 'user_subarea.id' )
->get();
Any help will be much appreciated.
I found by myself the answer it was just to add a lefjoin in the first join. It is not in the laravel docs but works too.
$query = DB::table('subarea')
->lefjoin('user_subarea', function($join)
{
$value = \Auth::user()->id;
$join->on( 'subarea.id', '=', 'user_subarea.subarea_id')->where('user_subarea.user_id', '=',$value);
})
->leftJoin('branch', 'subarea.area_id', '=', 'branch.id')
->select('branch.name', 'subarea.name as subarea', 'user_subarea.active_search_lawyer', 'user_subarea.id' )
->get();
Try this one, If you get a problem, please comment.
$value = \Auth::user()->id;
$query = DB::table('subarea')
->where('user_subarea.user_id', '=',$value)
->leftJoin('user_subarea', 'subarea.id', '=', 'user_subarea.subarea_id')
->leftJoin('branch', 'subarea.area_id', '=', 'branch.id')
->select('subarea.name AS subname','subarea.area_id', 'branch.name', 'user_subarea.id','user_subarea.lawyer_id','user_subarea.active_search')
->get();

Categories