Laravel whereIn array repetition - laravel

$item_ids = Cookie::get('name');
if(!is_array($item_ids)){
$items = Item::find($item_ids)->get();
}
$items = DB::table('items')
->whereIn('id', $item_ids )
->get();
dd($items);
$item_ids in dd($item_ids)
array:5 [▼
0 => "2"
1 => "2"
2 => "2"
3 => "4"
4 => "6"
]
As you can see in $item_ids 2 was repeated 3 times and I only get one. How to repeat it also 3 times. Is there any Query Builder could do this?

Query builder looks in the database for id = 2 with the whereIn method. There is only one item with id 2 in the database so it only returns one record.
However you can loop through your all your ids again and pull these from your database results. Do this for every id so you get multiple results for same id.
Something like this:
$item_ids = Cookie::get('name');
if(!is_array($item_ids)){
$items = Item::find($item_ids)->get();
}else{
$items = [];
$dbItems = Item::whereIn('id',$item_ids)->get();
foreach($item_ids as $id){
$items[] = $dbItems->first(function ($key, $value) use ($id) {
return $value->id == $id;
});
}
}
dd($items);

Related

How to separately implode data, based on ID or unique NAME?

I have database like this
id
name
numbers
1
Kathy
5
2
Kathy
15
3
Kathy
25
4
William
5
5
William
10
and I'm trying to retrieve and save it like this
id
name
numbers
1
Kathy
5.15.25
2
William
5.10
So I made a code like this to implode and save the data
$arr_name = [];
$arr_numbers = [];
$arr_implode = [];
$data= MyDatabase::all();
foreach ($data as $data) {
if ($data->name == $data->name) {
$arr_numbers [] = $data->numbers;
} else {
$arr_numbers [] = $data->numbers;
}
$arr_implode[$data->name] = implode('.', $arr_numbers);
}
but what I get when I use dd($arr_implode); is like this, so I haven't tried saving the data in my database.
array:2 [▼
"Kathy" => "5.15.25"
"William" => "5.15.25.5.10"
]
What should I do to get the desired output? sorry, I'm not really good at arrays and stuff
You can use DB::raw to format them during the query
e.i.
use Illuminate\Support\Facades\DB;
return DB::table('table_name')->select([
DB::raw('ROW_NUMBER() OVER( ORDER BY name ) as id'),
'name',
DB::raw('group_concat(numbers SEPARATOR ".") as numbers')
])->groupBy('name')->get();
OR
Just query all the data and format the Collection
e.i.
use Illuminate\Support\Facades\DB;
$data = DB::table('table_name')->select(['id','name','numbers'])->get();
or if you have a model for that table
$data = Model::select(['id','name','numbers'])->get();
then format it the way you want
return $data
->groupBy('name')
->values()
->map( fn ( $item, $key) => [
'id' => $key+ 1,
'name' => data_get($item, '0.name'),
'numbers' => implode('.', $item->pluck('numbers')->all() )
]);

laravel get() return 2 rows but foreach gives only the last row()

in order details table i have 2 row . When I use get() it gives 2 rows. But in foreach loop it only gives the last row.
In Controller:
$orderdetail = DB::table('order_details')->where('order_id',$eid)->get();
print_r($orderdetail);
$data =array();
foreach($orderdetail as $odetail){
$data['id'] = $odetail->product_id;
}
dd($data);
output:
following is the output
Get() result:
[0] (
[id] => 832
[product_id] => 1090
)
[1] (
[id] => 833
[product_id] => 1133
)
Foreach loop output
array:1 [▼
"id" => 1133
]
You overwrite in $data['id'] in foreach loop ,so it has one member
,you can use one of this code:
$data =array();
foreach($orderdetail as $key=>$odetail){
$data[$key]['id']= $odetail->product_id;
}
dd($data);
OR
$data=DB::table('order_details')->where('order_id',$eid)->get()->pluck('product_id);
OR
$data =array();
$i=0
foreach($orderdetail as $odetail){
$data[$i++]['id']= $odetail->product_id;
}
dd($data);
thanks every one for your answer. I solved it following way:
foreach($orderdetail as $key=>$odetail){
$data[$key]['id']= $odetail->product_id;
}
You are replacing array so its storing last data
$orderdetail = DB::table('order_details')->where('order_id',$eid)->get();
$data =[];
foreach($orderdetail as $odetail){
$data[]= $odetail->product_id;
}
dd($data);
if you need id as key then
$data =[];
foreach($orderdetail as $odetail){
$data['id'][]= $odetail->product_id;
}
or
$data[]['id']= $odetail->product_id;
or Simple way is to use pluck
$orderdetail = DB::table('order_details')->where('order_id',$eid)->pluck('product_id');

How to get data using foreach eloquent

I have a problem to get data using forach eloquent in laravel 6.
To get value which I want to use in foreach
$array_suspect_idBLE = Transaction::
select('id_ble')
->where('id_user',$suspect_id)
->where('updated_at','>=',$suspect_in)
->where('updated_at','<=',$suspect_out)
->pluck('id_ble');
The output
Illuminate\Support\Collection {#281
#items: array:5 [
0 => 18
1 => 6
2 => 12
3 => 16
4 => 10
]
}
and the foreach
foreach($array_suspect_idBLE as $arr){
$suspect_list = Transaction::
select('id_transaction','id_user','id_ble')
->where('id_user','<>',$suspect_id)
->where('updated_at','>=',$suspect_in)
->where('updated_at','<=',$suspect_out)
->where('id_ble', $arr->array_suspect_idBLE)
->get();
}
And the error is
message: Trying to get property 'array_suspect_idBLE' of non-object
The expected result are all id_transaction, id_user, id_ble that connect to array_suspect_idBLE 18,6,12,16,10
Any help would be appreciated.
Thank you
The problem is that the pluck() method returns an array of values. You are treating it as if it returns a collection of objects.
The solution would be to change it into this:
foreach($array_suspect_idBLE as $value) {
$suspect_list = Transaction::
select('id_transaction','id_user','id_ble')
->where('id_user','<>',$suspect_id)
->where('updated_at','>=',$suspect_in)
->where('updated_at','<=',$suspect_out)
->where('id_ble', $value)
->get();
}

laravel collection nested query

I'm new with laravel collection . i just want to make this query with collection
DB::select(SELECT id, user_id, created_at,latitude,longitude
FROM coordinates
WHERE created_at IN (
SELECT MAX(created_at)
FROM coordinates
GROUP BY user_id));
according to the document https://laravel.com/docs/6.x/collections
this what i did and it gives me all the data
$this->data['information'] = collect($response->json()['items']);
Edit:
simply i need to produce that query (that i mentioned above) by using Collection.
This is the contents of $response->json()['items']
"#items: array:17 [▼ 0 => array:9 [▼ "id" => 977777779 "platform_id" => "msaeed" "platform_type" => 1 "status" => 1 "longitude" => 1.1 "latitude" => 1.1 "created_by" => "NMF" "created_at" => "2019-10-27T21:00:00Z" "updated_at" => "2019-10-28T07:58:36Z""
any help would be appreciated
Here is the query.
$data = collect($response->json()['items']);
$data = $data->whereIn('created_at', $data->sortByDesc('created_at')
->groupBy('user_id')
->pluck('0.created_at'))
->onlyKeys(['id', 'user_id', 'created_at', 'latitude', 'longitude']);
The equivalent for the subquery:
SELECT MAX(created_at)
FROM coordinates
GROUP BY user_id
is
$data->sortByDesc('created_at') // we use sortByDesc to produce the same result as `MAX`.
->groupBy('user_id')
->pluck('0.created_at') // then to get the max value, just get the first array after grouping.
To achieve the select statement, we need to create a little macro, i've named it onlyKeys:
use Illuminate\Support\Arr;
Collection::macro('onlyKeys', function ($keys) {
return $this->map(function ($value) use ($keys) {
$tmpValue = (array) $value;
if (is_array($tmpValue)) {
$value = Arr::only($tmpValue, $keys);
}
return $value;
});
});
You can register the macro in your AppServiceProvider.php.
PS. Why you need to querying using Collection? Is that data not come from DB?
You want to collect array recursive
Unfortunately laravel does not have this feature:
you can write it on your own.
if you have helpers file you can write this method:
function recursive_collect($array){
foreach ($array as $key => $value) {
if (is_array($value)) {
$value = recursive_collect($value);
$array[$key] = $value;
}
}
return collect($array);
}
Or You can implement macro in your AppServiceProvider:
\Illuminate\Support\Collection::macro('recursive', function () {
return $this->map(function ($value) {
if (is_array($value) || is_object($value)) {
return collect($value)->recursive();
}
return $value;
});
});
Hope this helps you

How to get 3 conditions in laravel

guys so I want to get 3 conditions in controller Laravel, So I build a post with the comment system. My comment has 3 conditions, from default condition it will get value = 0, when is approved it will get value = 1, when it's denied it will give value = 2. I want to get 3 conditions to count how many it is because I want to build another value like value = 3 or 4 or 5 for another condition so I won't use get all.
Here is my comment controller function code
private function getCountComment()
{
$user = Auth::user();
$comcount = $user->competitions;
foreach ($comcount as $key => $value) {
$count = Comment::where('id_post', $value->id)
->where('is_accepted', '=', 0 AND 1 AND 3)
->count();
$comcount[$key]->comment_to_count = $count;
}
return $comcount;
}
I try that code but only get the first condition is_accepted = 0.
Hope you guys can help me.
Try this code
private function getCountComment(){
$user = Auth::user();
$comcount = $user->competitions;
foreach ($comcount as $key => $value) {
$comcount[$key]->comment_to_count = Comment::where('id_post', $value->id)->whereIn('is_accepted', [0,1,3])->count();
}
return $comcount;
}
or you can
Comment::where('id_post', $value->id)->where(function($query) {
$query->where('is_accepted', '=', 0)
->orWhere('is_accepted', '=', 1)
->orWhere('is_accepted', '=', 3)
})->count();

Resources