Get latest distinct value of a filed in Laravel - php

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

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;

Getting best seller courses

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"

can we avoid eloquent in large no of records

I am using laravel eloquent and have condition where thousands of records inside database so when using eloquent relationship my query is executing slow. Should i avoid using eloquent in these satuations or any other way?
here is mysql query
$leads=Lead::select($col)
->join("gc_od_leads_detail as ld", "gc_od_leads.leads_id", "=", "ld.ld_leads_id")
->join("gc_od_chat as c", "gc_od_leads.leads_chat_id", "=", "c.chat_id")
->join("gc_od_group as g", "c.chat_group_id", "=", "g.group_octachat_id")
->where('c.chat_tags','sales')
->whereIn('c.chat_group_id',$filter['groups']);
if(!empty($filter['keyword'])) {
$leads=$leads->where(function ($q) use ($filter) {
$q->where('ld_name','like', "%".$filter['keyword']."%")
->orWhere('ld_email','like', "%".$filter['keyword']."%")
->orWhere('ld_phoneno','like', "%".$filter['keyword']."%");
});
}
if(!empty($filter['startDate']) && !empty($filter['endDate'])){
$leads=$leads->whereBetween('leads_created_date', [$filter['startDate']." 00:00:00",$filter['endDate']." 23:59:59"]);
}
$leads=$leads->orderBy('leads_created_date','desc');
return $leads;
}
I have more than 500 000 recordings in side messages and chats table. i changed query in eloquent and debugged it
Query:
Lead::select('leads_id','leads_chat_id')->with(["detail"=>function($q){
$q->select("ld_leads_id");
}])->with(["chat"=>function($q){
$q->select("chat_id")->where(['chat_status'=>1]);
}])->where("leads_status",1)->get();
Debuging Ouput
array:3 [▼
0 => array:3 [▼
"query" => "select `leads_id`, `leads_chat_id` from `gc_od_leads` where `leads_status` = ?"
"bindings" => array:1 [▼
0 => 1
]
"time" => 14.85
]
1 => array:3 [▼
"query" => "select `ld_leads_id` from `gc_od_leads_detail` where `gc_od_leads_detail`.`ld_leads_id` in (2278918, 2278919, 2278920, 2278921, 2278922, 2278923, 2278924, 22789 ▶"
"bindings" => []
"time" => 0.59
]
2 => array:3 [▼
"query" => "select `chat_id` from `gc_od_chat` where `gc_od_chat`.`chat_id` in (3496457, 3496458, 3496459, 3496460, 3496461, 3496462, 3496463, 3496464, 3496465, 3496466, 34 ▶"
"bindings" => array:1 [▶]
"time" => 4.21
]
]
i above output you can see that it get all records of leads first then going to lead detail and chats table if i only want to find out the leads having chat status =1 it will still query all leads this is what slowing my query
where we use join it will not work in this way i think which will save time and space both that's my i post this question i think a lot of people having same problem and no one discuss this point
Let's take a look at one part of this.
if(!empty($filter['keyword'])) {
$leads=$leads->where(function ($q) use ($filter) {
$q->where('ld_name','like', "%".$filter['keyword']."%")
->orWhere('ld_email','like', "%".$filter['keyword']."%")
->orWhere('ld_phoneno','like', "%".$filter['keyword']."%");
});
}
This keyword-matching scheme is inherently, and disastrously, slow. It's slow in both Eloquent and native SQL. There's no way it can work in MySQL without doing a full table scan. That is, it must examine every row of your table looking for matches and cannot, in MySQL, exploit any indexed lookup scheme. Why?
column LIKE 'constant%'
can look at an index on column and quickly find any value starting with 'constant'. But
column LIKE '%constant%'
has to look at every value in the table. The leading % makes the index lookup useless.
In MySQL you would be wise to investigate MySQL's FULLTEXT searching as a way of handling your keyword lookup. (Recent versions of postgreSQL can handle this sort of query directly with a different kind of index, but not MySQL.)

collection not add pushing to subarray

I am using MongoDB and in the past I have been able to use the following to insert or add to a sub array that was already in the DB
Here is my issue, every day we take a look at the itunes top 100 and we insert the songs and artist into our collection, well infact we use two collections to do this job
but the one I am having issue with is the one that we store every single song and artist that has ever appeared in the iTunes top 100.
see code below
$collection = static::db()->itunes_collection_australia;
$document = $collection->findOne(array('song' => (string)$entry->imname, "artist"=>(string)$entry->imartist));
if (null !== $document) {
$collection->update(
array(array('song' => (string)$entry->imname, "artist"=>(string)$entry->imartist)),
array('$push' => array("date" => array('$each'=> array((string)$date)),"chartno"=> array('$each'=> array($a))),
));
}
else
{
$collection->insert(array("song"=>(string)$entry->imname, "artist"=>(string)$entry->imartist,"preview"=>(string)$preview,"cd_cover"=>(string)$cover, "price"=>(string)$price,"date"=>array((string)$date),"chartno"=>array($a)));
}
what should be happening is if the artist and song is found to already be the the collection , it should update. at the moment it is not running anything.
and if it is updating its not doing it right.
You see the "date" field should be showing multiple dates same with the chartno it should also be showing what position it was in the charts on that day.
here is how it should look when first inserted.
{
"_id" : ObjectId("52ea794d6ed348572d000013"),
"song" : "Timber (feat. Ke$ha)",
"artist" : "Pitbull",
"preview" : "http://a1264.phobos.apple.com/us/r1000/030/Music6/v4/48/30/3c/48303ca0-c509-8c15-4d4a-7ebd65c74725/mzaf_5507852070192786345.plus.aac.p.m4a",
"cd_cover" : "http://a1082.phobos.apple.com/us/r30/Music6/v4/64/41/81/644181ba-d236-211d-809e-057f4352d3d8/886444273480.170x170-75.jpg",
"price" : "$2.19",
"date" : [
"2014-01-29T07:10:38-07:00"
],
"chartno" : [
20
]
}
when the script sees it is back in the top 100 it should add it to the date and chartno fields.
like so
{
"_id" : ObjectId("52ea794d6ed348572d000013"),
"song" : "Timber (feat. Ke$ha)",
"artist" : "Pitbull",
"preview" : "http://a1264.phobos.apple.com/us/r1000/030/Music6/v4/48/30/3c/48303ca0-c509-8c15-4d4a-7ebd65c74725/mzaf_5507852070192786345.plus.aac.p.m4a",
"cd_cover" : "http://a1082.phobos.apple.com/us/r30/Music6/v4/64/41/81/644181ba-d236-211d-809e-057f4352d3d8/886444273480.170x170-75.jpg",
"price" : "$2.19",
"date" : [{
"2014-01-30T07:10:38-07:00"
},{2014-01-31T07:10:38-07:00}],
"chartno" : [
{20},{30}
]
}
however that is not happening infact nothing seems to be getting added.
I am wondering if I have done something wrong? Well clearly I have.
I have also tried the following '$addToSet' but with no success.
your update statement is wrong. you have too many arrays on first parameter. try this:
$collection->update(
array('song' => (string)$entry->imname, "artist"=>(string)$entry->imartist),
array('$push' => array("date" => array('$each'=> array((string)$date)),"chartno"=> array('$each'=> array($a))),
));

Categories