Trending query Laravel - php

Right now I have a subquery to get the count of payments for the current month and then getting the 4 products with the highest payment_count. This query works fine but I'm wondering if there's a more simple way to do the same since its getting difficult to read.
$latestPayments = DB::table('payments')
->select('product_id', DB::raw('COUNT(*) as payments_count'))
->whereMonth('created_at', Carbon::now()->month)
->groupBy('product_id');
$trendingProducts = DB::table('products')
->joinSub($latestPayments, 'latest_payments', function ($join) {
$join->on('products.id', '=', 'latest_payments.product_id');
})->orderBy('payments_count', 'DESC')->take(4)->get();

This did it!
$trendingProducts = Product::withCount(['payments' => function($query) {
$query->whereMonth('created_at', Carbon::now()->month);
}])->orderBy('payments_count', 'DESC')->take(4)->get();

If you are using eloquent query with relational database you can do like this:
$latestPaymentWithTrendingProduct = App\Payment::with(['products', function($product) {
$product->orderBy('payments_count', 'DESC')->take(4);
}])->whereMonth('created_at', date('m'))->get()->groupBy('product_id');
This will lessen the code but still do the same thing.

Related

Combine with Relation with where sentence in Laravel8

I'm learning Laravel's relations. I'm having problems with the 2nd line.
I would like to display records that Auth::user table's br_name column = Partner table's br_name column matches.
Could you teach me the right code please?
UPDATE
public function mybr()
{
$blogs = Blog::with('user','category','partner')
->where('App\Partner::partner()->br', Auth::user()->br_name)//I'm having problem this line
->where(function($query){
$query->where('status', '=','new');
->orWhere('status', '=', 'old');
})->paginate(250);
return view('blogs.mybr')->with('blogs',$blogs);
}
You could try the following code, and I have done some query refactoring too.
Like I have used whereIn
$blogs = Blog::with(['user','category','partner' => function ($query) {
$query->where('br', '=', Auth::user()->br_name);
}])->whereIn('status',['new','old'])
->paginate(250);

How do you filter the user with hasRole() in Laravel 5 within relational query?

I want to filter my query and return only if the user hasRole "Premium" and limit the result to 10.
Along with this query is a count of records which Conversion has and sort it in DESC order by total column.
Right now I have a working query that returns the count of Conversion and with a User but without user filter Role.
// Model Conversion belongs to User
// $from & $end uses Carbon::createDate()
// Current code
$query = Conversion::select('user_id',DB::raw('COUNT(*) as total'))
->whereBetween('created_at', [$from,$end])
->where('type','code')
->where('action','generate')
->whereNotNull('parent_id')
->with('user')
->groupBy('user_id')
->orderBy('total', 'DESC')
->take(10)
->get();
// current result
foreach ($query as $q) {
$q->user->name; // To access user's name
$q->total; // To access total count
}
// I tried this but no luck
$query = Conversion::select('user_id',DB::raw('COUNT(*) as total'))
->whereBetween('created_at', [$from,$end])
->where('type','code')
->where('action','generate')
->whereNotNull('parent_id')
->with('user', function($q) {
$q->hasRole('Premium');
})
->groupBy('user_id')
->orderBy('total', 'DESC')
->take(10)
->get();
You need to use whereHas instead of with, like this:
->whereHas('user', function ($query) {
$query->where('role','Premium');
})
Use the whereHas() instead of with(). Also, you can't use hasRole() if it's not a local scope:
->whereHas('user.roles', function($q) {
$q->where('name', 'Premium');
})

Laravel 5.4 joining two tables

I'm quite lost here. I am trying to get the list of people who are on the Records table which aren't on the Profiles tables which has the specific course (e.g Psychology) and year (e.g 2011). So far, this is what I came up with and unfortunately it's not working.
$check = Record::join('Profiles', function ($join) {
$join->on('Records.firstname', '!=', 'Profiles.firstname');
$join->on('Records.lastname', '!=', 'Profiles.lastname');
$join->on('Records.middlename', '!=', 'Profiles.middlename');
})
->select('Records.*', 'Profiles.*')
->where('Records.year', '2011')
->where('Records.course', 'Psychology')
->get();
dump($check);
Is there any way that I can go around about this? I'm new to this. Thanks in advance. Advises and tips on joining tables would be greatly appreciated.
Please try a NOT EXISTS subquery:
use Illuminate\Database\Query\Builder;
$check = \DB::table('Records')
->whereNotExists(function(Builder $query) {
$query->select(\DB::raw(1))
->from('Profiles')
->whereRaw('Records.firstname = Profiles.firstname')
->whereRaw('Records.middlename = Profiles.middlename')
->whereRaw('Records.lastname = Profiles.lastname');
})
->select('firstname', 'middlename', 'lastname')
->where('year', 2011)
->where('course', 'Psychology');
->get();
I would look at doing a left outer join and then selecting the records that have a null profile name.
$check = Record::leftJoin('Profiles', function ($join) {
$join->on('Records.firstname', '=', 'Profiles.firstname');
$join->on('Records.lastname', '=', 'Profiles.lastname');
$join->on('Records.middlename', '=', 'Profiles.middlename');
})
->select('Records.*', 'Profiles.*')
->where('Records.year', '2011')
->where('Records.course', 'Psychology')
->whereNull('Profiles.firstname')
->get();

Laravel OrderBy Relationship count with pagination

I have many projects and each has many orders, some completed, some not.
I want to order them by the amount of completed orders like this:
$products = $products->orderBy(function($product) {
return $product->orders->where('status', 2)->count();
})->paginate(15);
I know the order call doesn't work like this but this is the best was show the problem. SortBy doesn't work because I want to use pagination.
Finally found a good solution for the problem:
$products = $products->join('orders', function ($join) {
$join->on('orders.product_id', '=', 'products.id')
->where('orders.status', '=', 2);
})
->groupBy('products.id')
->orderBy('count', $order)
->select((['products.*', DB::raw('COUNT(orders.product_id) as count')]))->paginate(50);
Try this if it works:
$categories = Prodcuts::with(array('orders' => function($query) {
$query->select(DB::raw('SELECT * count(status) WHERE status = 2 as count'))
$query->orderBy('MAX(count)')
}))->paginate(15);
return View::make('products.index', compact('categories'));
Note: This is not tested.
From 5.2 on wards you can use the withCount for counting relationship result.
In this case the
$products = $products->withCount(['orders' => function ($query) {
$query->where('status', 2);
}]);
Reference : https://laravel.com/docs/5.2/eloquent-relationships

trying to Join 2 table query in Fluent laravel 4

Im trying to Joing 2 table in Fluent trough my Model i run the query on mysql client and give me the return i want.
this is the standard query
select `songlist`.*, `queuelist`.* from `songlist` inner join `queuelist` on `songlist`.`id` = `queuelist`.`songID` where `queuelist`.`songID` = songlist.ID and `songlist`.`songtype` = 'S' and `songlist`.`artist` <> "" order by `queuelist`.`sortID` ASC limit 4
it does return the data im looking for.
now on my model using fluent.
i did like this.
public static function comingUp()
{
$getcomingUp = DB::table('songlist')
->join('queuelist', 'songlist.id', '=', 'queuelist.songID')
->select('songlist.*','queuelist.*')
->where('queuelist.songID', '=', 'songlist.ID')
->where('songlist.songtype', '=', 'S')
->where('songlist.artist', '<>', '')
->orderBy('queuelist.sortID', 'ASC')
->take('4')
->get();
return $getcomingUp;
}
and my controller to test if i get the data look like this
public function getComingUp()
{
$getcomingUp = Radio::comingUp();
foreach ($getcomingUp as $cup)
{
echo $cup->title;
}
// return View::make('comingup', compact('comingup'));
}
as you can see the foreach is no returning any data there is nothing wrong with the query because laravel give me no error at all. but i cant just get the foreach to display the data im looking for.
i try with $cup->songlist.title;
and it dont work ether.
Thanks any help will be appretiated. againg sorry for my English.
You can do something like this.
public static function comingUp()
{
$getcomingUp = DB::table('songlist')
->select('songlist.*','queuelist.*')
->join('queuelist', 'queuelist.songID', '=', 'songlist.id')
->where('songlist.songtype', '=', 'S')
->where('songlist.artist', '<>', '')
->orderBy('queuelist.sortID', 'ASC')
->take('4')
->get();
return $getcomingUp;
}

Categories