I have the following two collections:
Collection {#402 ▼
#items: array:1 [▼
4007 => "4007 - Container Deposit - 18.00 Drum - In Stock: 0.00"
]
}
Collection {#398 ▼
#items: array:3 [▼
1000 => "1000 - Acetone - 162.00 KG - In Stock: 10000.00"
1001 => "1001 - Acetone - 15.80 KG - In Stock: 0.00"
24662 => "24662 - 1L Untd Antifreeze Orange FO2272A60(Prem - 1.00 Litre - In Stock: 0.00"
]
}
Using Laravel's collection merge function:
$merged = $ref_prod_containers->merge($ref_cust_prod);
dd($merged);
I get the following:
Collection {#397 ▼
#items: array:4 [▼
0 => "4007 - Container Deposit - 18.00 Drum - In Stock: 0.00"
1 => "1000 - Acetone - 162.00 KG - In Stock: 10000.00"
2 => "1001 - Acetone - 15.80 KG - In Stock: 0.00"
3 => "24662 - 1L Untd Antifreeze Orange FO2272A60(Prem - 1.00 Litre - In Stock: 0.00"
]
}
However I wish to retain the original keys. The merge function is removing them and replacing with 0,1,2,3.
Thanks, Julian
You can use Laravel Collection's union() method. Beware that this behaves differently from merge() when dealing with duplicate keys: if the same key is present in both $array1 and $array2 and you go $merged = $array1->union($array2), then the value of $array1 will end up in the $merged collection, and the value of $array2 will be discarded (Laravel union documentation).
I would try to use string keys for the merging and merged collection.
From the laravel docs section collections, function merge()
If the given array's keys are numeric, the values will be appended to the end of the collection:
Related
I am working on a Laravel application, users can place football bets.
This is a simplified version of my tables:
users
- id
- name
bets
- id
- id_user
- cost
- profit (e.g. can be 0 if user lost this bet or any integer value if won)
- created_at (default laravel column, this should be used to group bets by month)
I need to show a chart with ROI (not looking for the formula, this can be simplified as calculateROI in your comments) of last six months from current one.
Let's assume current month is july, how can i write a query or use Eloquent to have something like:
[
[
"february" => 2%
],
[
"march" => 0%
],
[
"april" => 100%
],
[
"may" => 500%
],
[
"june" => 13%
],
[
"july" => 198%
],
]
I am trying to get the daykey from dates which i need to use in Array to fill "0" if data is not available .
My dates start from "2022-02-08" and end with "2022-03-10".
Trying to get daykey using code
$rahul = Buffalomilkrecord::select(DB::raw('date'), DB::raw('sum(totalmilk) as totalmilk, DATE_FORMAT(date,"%d") as "daykey"'))
->whereBetween('date', [$olddate, $todaydate] )
->groupBy(DB::raw('date'))
->orderBy('date','asc')
->get();
the out put i am getting
array:31 [▼
0 => "2022-03-01"
1 => 0
2 => 0
3 => 0
4 => 0
5 => 0
6 => 0
7 => "2022-02-08"
8 => 0
9 => 0
10 => 0
11 => 0
12 => 0
13 => 0
14 => 0
15 => "2022-02-16"
16 => "2022-02-17"
17 => "2022-02-18"
18 => "2022-02-19"
19 => "2022-02-20"
20 => "2022-02-21"
21 => "2022-02-22"
22 => "2022-02-23"
23 => 0
24 => "2022-02-25"
25 => "2022-02-26"
26 => 0
27 => 0
28 => 0
29 => 0
30 => 0
]
$ddtest = [0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0];
foreach($rahul as $order)
{
$ddtest[$order->daykey-1] = $order->date;
}
Here i am expecting to start array with
0 => "2022-02-08" and so on.... as date start in Month and end with March
I feel i am doing some error in query but can not find where i am doing mistake..
Thanks in advance for help
The SQL will only return exiting data, so if there is no data for this specific day, you wont get a row for this day. This is something you have to take care outside of the query.
You need to build the date range by yourself. for example like this:
I have 2 dates in PHP, how can I run a foreach loop to go through all of those days?
Build one array with "default" entries per day with 0 values and than merge them with the sql result.
How do i query to make total count per day based on a name or an id?
id
name
1
Facebook
2
Twitter
3
Reddit
id
page_id
social_id
visited_at
1
1
1
2021-03-27
2
1
1
2021-03-27
3
1
2
2021-03-27
4
1
2
2021-03-27
5
1
3
2021-03-27
6
1
3
2021-03-27
7
1
1
2021-03-28
8
1
1
2021-03-28
9
1
2
2021-03-28
10
1
2
2021-03-28
11
1
3
2021-03-28
12
1
3
2021-03-28
With the following query i get count of click on all social anchors per day, but i want to show in the chart also which social anchor has been clicked on that day.
$social_stats= Social::join('social_statistics', 'social_statistics.social_id','socials.id')
->select( array(
'social_statistics.visited_at as visited_at',
DB::raw('count(*) as count'),
)
)
->orderBy('visited_at')
->groupBy('visited_at')
->pluck('count','visited_at')
->all();
Need to render a Chart that shows by day the count of click on different social.
$social_bar_chart = new SocialBarChart;
$visited_at = collect(array_keys($this->social_bar));
$social_bar_labels = $visited_at->map(function ($date) {
return Carbon::parse($date)->format('d/m');
})->toArray();
$social_bar_chart->labels($social_bar_labels)
->dataset('Social Count', 'bar', array_values($this->social_bar))
->options([
'tooltip' =>['show' => true],
'backgroundColor' => '#54a0ff',
]);
Eagerloading with pagination is simple:
Model::with(['relation1', 'relation2'])->paginate();
There are 6 models M1, ..., M6 and model M1 has foreign key to models M2, ..., M6. There are at least 2,000,000 records in each model and model M1 has more than 10,000,000 records. The following statement
M1::paginate();
is fast enough but when relations are included, it takes more than 45 seconds to return the results. To improve the performance, I need to run the M1::paginate(); at the beginning, then include other relations.
My solution is to loop through the collection, gather the ids and add the relations. I would like to know does such thing have been implemented in Laravel before?
Whenever you are unsure about how the queries made, open the console (php artisan tinker) and write the following:
DB::listen(fn($q) => dump([$q->sql, $q->bindings, $q->time]))
For each query you make (in the current console session), you'll get an array containing the SQL, the bindings and the time it actually takes for the database to return the data (this does not take into account how long it takes PHP to turn these results into an Eloquent Collection).
For example, for a Model (A) that has one hasMany relation with another Model (B), look at the output below:
>>> DB::listen(fn($q) => dump([$q->sql, $q->bindings, $q->time]))
=> null
>>> App\Models\A::with('b')->get()->first()->id
array:3 [
0 => "select * from "a""
1 => []
2 => 0.0
]
array:3 [
0 => "select * from "b" where "b"."a_id" in (1, 2, 3, 4, 5,
6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26,
27)"
1 => []
2 => 0.0
]
=> 1
>>> App\Models\A::with('b')->paginate(5)->first()->id
array:3 [
0 => "select count(*) as aggregate from "a""
1 => []
2 => 0.0
]
array:3 [
0 => "select * from "a" limit 5 offset 0"
1 => []
2 => 0.0
]
array:3 [
0 => "select * from "b" where "b"."a_id" in (1, 2, 3, 4, 5)"
1 => []
2 => 0.0
]
As you can see, the pagination has an effect on the relationship queries made.
I have an array output in laravel, the structure looks like follows:
array:1 [
0 => {#35
+"id": 152
+"user_id": 123
+"post_id": 456
+"content": "impedit"
+"created_at": "04-09-2016 01:24"
+"updated_at": "2016-09-04 01:24:51"
}
]
How to test the array structure contains keys id、user_id ...?
I tried assertArrayHasKey('user_id', $array),but it shows failed.
Thanks.
Thanks for the #linuxartisan. Finally I convert the value object to array for testing.
$this->assertArrayHasKey('user_id', (array)$comment[0]);