Getting best seller courses - php

I'm trying to get best seller courses. but something is going wrong...
$items = DB::table('orders')->select('course_id', DB::raw('COUNT(course_id) as count'))
->groupBy('course_id')->orderBy("count", 'desc')->get();
$courseIds = [];
foreach($items as $item) {
array_push($courseIds, $item->course_id);
}
$bestSellings = Course::whereIn('id', $courseIds)->get();
So when i do dd on $courseIds i'm getting
array:3 [▼
0 => 4
1 => 1
2 => 2
]
and yes it's must be like that because most selling course is number 4 then goes number 1 and then number to but when i try dd on $bestSellings i'm getting 1 course then 2 course then 4 course : / why? what can i do?

If you are using MySQL, then you could use 'ORDER BY FIELD':
$fieldOrder = join(", ", $courseIds);
$bestSellings = Course::whereIn('id', $courseIds)
->orderByRaw("FIELD(id, $fieldOrder)")
->get();
See: https://www.mysqltutorial.org/mysql-order-by/ "Using MySQL ORDER BY clause to sort data using a custom list"

Related

Laravel, display data where all Ids are matched

In controller index function
I'm picking up which news ids are matching with a pack id:
$content_pack_news_array = DB::table('content_pack_news')->where('content_pack_id' , $content_pack_id)->get();
Using dd I get this result which I need to access news_id of all elements in it
Illuminate\Support\Collection {#3017 ▼
#items: array:2 [▼
0 => {#2376 ▼
+"news_id": 2
+"content_pack_id": 2
}
1 => {#3010 ▼
+"news_id": 4
+"content_pack_id": 2
}
]
}
How to return data that matched with ids:
"news_id": 2
"news_id": 4
Inside:
$news = News::with(['media', 'assigned_content_packs'])->where('id' , $news_id)->get();
If I use
$content_pack_news = DB::table('content_pack_news')->where('content_pack_id' , $content_pack_id)->first();
It works but it gets only first matching item to display.
Any help appreciated.
You can use pluck, to get the ids out.
$newsIds = DB::table('content_pack_news')
->where('content_pack_id' , $content_pack_id)
->pluck('news_id');
Pluck works great in combination with whereIn(), that checks a column against an array.
$news = News::with(['media', 'assigned_content_packs'])
->whereIn('id' , $newsIds)
->get();
You can do it in single query using sub query as:
$news = News::with(['media', 'assigned_content_packs'])
->whereIn('id', function($query) use($content_pack_id){
$query->select('news_id')
->from('content_pack_news')
->where('content_pack_id', $content_pack_id);
})
->get();
if i correct you only asking the first.
$content_pack_news = DB::table('content_pack_news')->where('content_pack_id' , $content_pack_id)->first();
change it to get(); then you get all records.
$content_pack_news = DB::table('content_pack_news')->where('content_pack_id' , $content_pack_id)->get();

Laravel Getting id's from a table and inserting them into another table

Trying to get matching id's from a table and inserting them again in the same table under differnet relationship.
$contentPack = ContentPack::find($id);
$cloned_pack_goals = DB::table('content_pack_goal')->where('content_pack_id' , $contentPack->id)->get();
$cloned_pack_goal_ids = $cloned_pack_goals->goal_id;
Produces Exception
Exception
Property [goal_id] does not exist on this collection instance.
dd($cloned_pack_goals); outputs:
Illuminate\Support\Collection {#2466 ▼
#items: array:2 [▼
0 => {#3129 ▼
+"goal_id": 4
+"content_pack_id": 2
}
1 => {#2467 ▼
+"goal_id": 9
+"content_pack_id": 2
}
]
}
How to get goal_ids from the output to insert them into the same table again but with a different relation?
$newPack = $contentPack->replicate();
DB::table('content_pack_goal')->insert(['content_pack_id' => $newPack->id,'goal_id' => $cloned_pack_goal_ids]);
Am doing something wrong when getting the ID's and when inserting them. tried using ->first(); it works but only one id gets inserted
$cloned_pack_goals is a collection, so you need to exclude goal_ids from all collection records separately.
This snippet may help you:
$cloned_pack_goal_ids = DB::table('content_pack_goal')->where('content_pack_id' , $contentPack->id)->pluck('goal_id')->toArray();
foreach($cloned_pack_goal_ids as $key => $goal_id) {
DB::table('content_pack_goal')->insert(['content_pack_id' => $newPack->id,'goal_id' => $goal_id]);
}
To get an array of only the Ids, use pluck() and toArray()
$cloned_pack_goal_ids = DB::table('content_pack_goal')
->where('content_pack_id' , $contentPack->id)
->pluck('goal_id') // returns a collection of only Ids.
->toArray(); // returns an array from the collection.
Write your query in this format this will give you the require output:
$cloned_pack_goals = DB::table('content_pack_goal')->where('content_pack_id' , $contentPack->id)->get()->toArray();
$cloned_pack_goal_ids = $cloned_pack_goals[0]->goal_id;

How to sum multiple rows into 1 group in laravel?

I'm doing export but don't know how to foreach calculate
get the employee's total time worked and how much the total amount.
data is retrieved from the database
$data = Clocks::orderBy('updated_at', 'desc')->get();
$row = [];
foreach ($data as $index) {
$row[] = array(
'0' => $index->user_id,
'1' => $index->total_time,
'2' => $index->earned_amount,
'3' => $index->bonus_pay,
);
}
return (collect($row));
I want to output it like this
user time amount bonus
1 25:30 400 20
3 9:00 150
Please help me, thank you for viewing this article.
I found a way
$data = Clocks::groupBy('user_id')
->selectRaw('SEC_TO_TIME( SUM(time_to_sec(`total_time`))) as total_time,
SUM(`earned_amount`) as earned_amount,
SUM(`bonus_pay`) as bonus_pay, user_id')
->get();

Querying sum of multiple aggregate columns (without groupBy)

I have a transactions table and I'm trying to get the total of each type.
To simply put it looks like this
id
type
credit_movement
1
top_up
10000
2
fee
-50
3
deduct
-1000
I am trying to get sum of each type to show as a report.
top_up: 10000
fee: 50
deduct: 1000
net_expense: 9850 [top_up - deduct - fee]
$types = [
'top_up' => ['top_up'],
'deduct' => ['deduct'],
'fee' => ['fee'],
'net_expense' => ['top_up', 'deduct', 'fee'],
];
$query = DB::table('transactions');
foreach ($types as $type => $fields) {
$query->selectSub(function ($query) use ($fields) {
return $query->selectRaw('SUM(credit_movement)')->whereIn('type', $fields);
}, $type);
};
$results = $query->get();
When I do this, I get:
1140 In aggregated query without GROUP BY, expression #1 of SELECT list contains nonaggregated column 'project.transactions.type'; this is incompatible with sql_mode=only_full_group_by..
When I change my database.mysql.strict = false, it works; however I want to make it work properly without needing to change the mysql config.
As of my understanding, this error indicates that I am only selecting aggregated columns, but in my case I don't actually want to groupBy() anything as this is just reports.
If I try to groupBy('type') it returns everything grouped by type, but the queries are only run within that group.
{
0: {
top_up: 10000,
deduct: 0,
fee: 0,
net_expense: 10000
}
1: {
top_up: 0,
deduct: -1000,
fee: 0,
net_expense: -1000
},
// etc...
}
Is there a way to obtain without changing strict to false?
{
0 => {
top_up: 10000,
deduct: -1000,
fee: -50,
net_expense: 9850
}
}
If I understand you correctly this might be very easy but again I might have not understood it right.
$result = DB::table('transactions')->selectRaw('type, SUM(credit_movement) as sum')->groupBy('status')->get();
This should return something like this:
type
sum
fee
-5656
topup
8758
deduct
-7625
For the total sum you can just do it in php which would make it easier
$net = $result->sum('sum'); // equals -5656+8758-7625
Hope this helps and let me know if I am wrong about it.
The problem with your approach is in the final column that is the sum of the other 3 so you can't use SUM because you don't have a column to group.
You could use a subquery but I think that the best solution is to add a little elaboration of the raw data that you get from a simpler query.
$query = DB::table('transactions')
->selectRaw('type, SUM(credit_movement) AS movements')
->groupBy('type');
$results = array_reduce($query->get(), function(array $res, array $value){
$res[$array['type']] = $array['movements'];
return $res;
}, []);
$results['net_expense'] = array_sum($results);

Get latest distinct value of a filed in Laravel

I want to query the latest + distinct name.
I got the distinct part to work, but they're not the latest.
I'm not sure how to do that in Laravel.
I’ve tried
$localDevices = Device::orderBy('created_at', 'desc')->groupBy('mac')->get();
$localDeviceName = [];
$i = 0;
foreach ($localDevices as $localDevice) {
foreach ($devices as $device) {
if($localDevice->mac == $device->device_mac ){
$localDeviceName[$i]['name'] = $localDevice->name;
$localDeviceName[$i]['mac'] = $device->device_mac;
$i++;
}
}
}
Database
I got
array:1 [▼
0 => array:3 [▼
"name" => "Apple Watch"
"img" => "/images/photos/devices/apple-watch.jpg"
"mac" => "080027E2FC7D"
]
]
I want it to show ps4 because it is the latest.
Try #2
tried update my
orderBy('created_at', 'desc') to orderBy('created_at', 'asc')
I got the same result.
Try #3
tried placing orderBy after groupBy
Device::groupBy('mac')->orderBy('created_at', 'desc')->get();
I got the same result.
Any hints / suggestions on that will much appreciated !
You are doing a groupBy on your mac value which isn't unique, your Apple watch and PS4 have the same mac, mysql first groups by then orders your grouped results. That's why you are always getting Apple watch.
What you want is to fetch the latest record from each group and for that you might write a Raw query, check this Retrieving the last record in each group

Categories