Laravel - Groupby and merge the other column - php

I have a collection like that, when i perform groupBy('name'), it return like this one
my question is how to merge the "id_area" key when i perform groupBy('name') ?
the expected result is more like this
"name" => "A"
"id_area" => [3, 1]
my eloquent code is
$x = Kegiatan::orderBy('name')->groupBy('name')->get();
$y = $x->map(function ($group) {
return ["name" => $group->name, "id_area" => $group->id_area];
});
dd($y);

Don't use groupBy() method of your query builder instead just get your data and then use groupBy() method of Illuminate\Support\Collection class
$collection = Kegiatan::orderBy('name')->get();
$grouped = $collection->groupBy('name');
$grouped->toArray();
Using groupBy() on query builder will group records by database query and using collection's groupBy() will group records once data is fetched by query

Related

How to create array with key => values from object{key, value}?

I solver this by this code
$service_list = Service::all();
$services = [];
foreach ($service_list as $item){
$services[$item['id']] = $item['name'];
}
but how to do that using php_array functions?
its for dropdown select
Not sure why you have to use PHPs built in array methods but we have pluck on the Query Builder and Collection class.
$services = Service::pluck('name', 'id');
// $services->all(); // for the actual array contained
This will only select the name and id in the query and give you a Collection keyed by the id only containing the name field.
$services = Service::all();
$services_array = $services->pluck('name', 'id')->all();
If you already have your collection of models (code above has queried for every field and hydrated models with the result) you can use pluck on the Collection to achieve the same result (though less efficient as it had to query for all fields, hydrate models, then pull those 2 fields from them)
Laravel 5.5 Docs - Query Builder - Retrieving Results
Laravel 5.5 Docs - Collections - pluck method
Use toArray() to convert the collection to an array, then use array_combine() to create an associative array from that.
$service_list = Service::all()->toArray();
$services = array_combine(array_column($service_list, 'id'), array_column($service_list, 'name'));
$service_list = Service::all()->toArray();
all() will return a collection. The collection supports a toArray() method

How can I use array_where in Laravel?

I have an array ($payments) returned by an Eloquent query with the following JSON encoded output:
[{"id":1, "user_id":"34","amount":"1000","status":"0","created_at":"2016-08-18 14:24:59","updated_at":"2016-08-18 14:24:59"},
{"id":3, "user_id":"33","amount":"300","status":"1","created_at":"2016-08-18 14:31:04","updated_at":"2016-08-18 14:33:20"},
{"id":4, "user_id":"33","amount":"1000","status":"0","created_at":"2016-08-18 14:31:27","updated_at":"2016-08-18 14:31:27"},
{"id":5, "user_id":"34","amount":"400","status":"1","created_at":"2016-08-18 14:42:02","updated_at":"2016-08-18 14:42:02"}]
I want to use the array_where() method in Laravel and filter $payments according this condition : status == 1, could anyone tell me how to do that?
If this is the result of an Eloquent query, it's not an array, it's a Collection. From the documentation:
All multi-result sets returned by Eloquent are an instance of the Illuminate\Database\Eloquent\Collection object
You can use the Collection's filter method, which takes a closure, and return the condition you want ('status' == 1) in the closure.
$filtered = $your_query_result->filter(function($value, $key) {
return $value->status == 1;
});
You may be surprised to find out that there is a php function called array_filter that does exactly that. Here it is in action
$array = [ ['id' => 1, 'status' => 0], ['id' => 2, 'status' => 1], ['id' => 3, 'status' => 0] ];
$array = array_filter($array, function ($item) {
return $item['status'] == 1;
});
Eloquents result cannot be json by default unless You call toJson() method.
Why not just add to Your database query condition?
Example:
$payments = Payment::where('status', '=', 1)->get(); // Payment is model
return response()->json($payments);
p.s. it's not recommended to get a big list of json data from db, parse it and filter it.
make better use of database and don't make Your life hard (:

Laravel 5.2 - pluck() method returns array

I'm trying to upgrade my project L5.1 -> L5.2. In upgrade guide there's one thing which isn't clear for me:
The lists method on the Collection, query builder and Eloquent query
builder objects has been renamed to pluck. The method signature
remains the same.
That's ok, rename refactoting from lists() to pluck() isn't a problem. But what with useful pluck() method which was in L5.0 and L5.1?
From the 5.0 documentation:
Retrieving A Single Column From A Row
$name = DB::table('users')->where('name', 'John')->pluck('name');
What is the alternative for old pluck() method in L5.2?
UPDATE:
Example:
var_dump(DB::table('users')->where('id', 1)->pluck('id'));
L5.1:
// int(1)
L5.2:
// array(1) { [0]=> int(1) }
The current alternative for pluck() is value().
In Laravel 5.1+, you can use the value() instead of pluck.
To get first occurence, You can either use
DB::table('users')->value('name');
or use,
DB::table('users')->where('id', 1)->pluck('name')->first();
laravel pluck returns an array
if your query is:
$name = DB::table('users')->where('name', 'John')->pluck('name');
then the array is like this (key is the index of the item. auto incremented value):
[
1 => "name1",
2 => "name2",
.
.
.
100 => "name100"
]
but if you do like this:
$name = DB::table('users')->where('name', 'John')->pluck('name','id');
then the key is actual index in the database.
key||value
[
1 => "name1",
2 => "name2",
.
.
.
100 => "name100"
]
you can set any value as key.
I use laravel 7.x and I used this as a workaround:->get()->pluck('id')->toArray();
it gives back an array of ids [50,2,3] and this is the whole query I used:
$article_tags = DB::table('tags')
->join('taggables', function ($join) use ($id) {
$join->on('tags.id', '=', 'taggables.tag_id');
$join->where([
['taggable_id', '=', $id],
['taggable_type','=','article']
]);
})->select('tags.id')->get()->pluck('id')->toArray();
In the original example, why not use the select() method in your database query?
$name = DB::table('users')->where('name', 'John')->select("id");
This will be faster than using a PHP framework, for it'll utilize the SQL query to do the row selection for you. For ordinary collections, I don't believe this applies, but since you're using a database...
Larvel 5.3: Specifying a Select Clause

Use an array in Laravel update query

I would like to push an array in Where Clause of Laravel Update Query.
Here is the update query.
DB::table('users')->where('id', 1)->update(array('votes' => 1));
Is it possible to use the query like below ??
$array_of_ids;
DB::table('users')->where($array_of_ids)->update(array('votes' => 1));
Thanks
Simply use whereIn:
$array_of_ids;
DB::table('users')->whereIn('id', $array_of_ids)->update(array('votes' => 1));
Please read the documentation carefully. In this case, all kinds of where statements are documented here: Query Builder - Selects
Try this query:
DB::table('users')->whereIn('id', $array_of_ids)->update(['votes' => 1]);
Using Model:
User::whereIn('id', $array_of_ids)->update(['votes' => 1]);
using the query builder: The query builder can also update existing records using the update method. The update method, like the insert method, accepts an array of column and value pairs containing the columns to be updated. You may constrain the update query using where clauses:
DB::table('users')
->where('id', 1)
->update(['votes' => 1]);

How to use query builder with sum() column and groupBy

How would I use query builder in Laravel to generate the following SQL statement:
SELECT costType, sum(amountCost) AS amountCost
FROM `itemcosts`
WHERE itemid=2
GROUP BY costType
I have tried several things, but I can't get the sum() column to work with a rename.
My latest code:
$query = \DB::table('itemcosts');
$query->select(array('itemcosts.costType'));
$query->sum('itemcosts.amountCost');
$query->where('itemcosts.itemid', $id);
$query->groupBy('itemcosts.costType');
return $query->get();
Using groupBy and aggregate function (sum / count etc) doesn't make sense.
Query Builder's aggregates return single result, always.
That said, you want raw select for this:
return \DB::table('itemcosts')
->selectRaw('costType, sum(amountCost) as sum')
->where('itemid', $id)
->groupBy('costType')
->lists('sum', 'costType');
Using lists instead of get is more appropriate here, it will return array like this:
[
'costType1' => 'sumForCostType1',
'costType2' => 'sumForCostType2',
...
]
With get you would have:
[
stdObject => {
$costType => 'type1',
$sum => 'value1'
},
...
]

Categories