[
{
"total": 71
},
{
"total": 66
}
]
How can i sum both numbers up to give me = 137. I have tried array_sum($array_result) but the spits and error saying :
array_sum() expects parameter 1 to be array, object given
this is my code
$result = DB::table('marks')->where([
['term', $request->term],
['subject', $request->subject],
['class', $student->class],
['arm', $student->arm],
])->select('total')->get();
return array_sum($result);
return redirect()->back()->with('success', 'Results marked successfully.');
If you just need to sum up total, use sum() Query Builder method:
$result = DB::table('marks')->where([
['term', $request->term],
['subject', $request->subject],
['class', $student->class],
['arm', $student->arm],
])->sum('total');
Easiest to put them in a collection and call sum() method.
Like that:
$sum = collect($yourArray)->sum('total');
You could do it with foreach and a temporary variable as well though.
$result = DB::table('marks')->where([
['term', $request->term],
['subject', $request->subject],
['class', $student->class],
['arm', $student->arm],
])->select('total')->get();
$result = $result->toArray();
Now you can simply do this as mentioned by devk
collect($result)->sum('total');
get() return collection. you directly perform actions on collections
like get()->sum('total')
I hope this helps.
Related
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);
I am working with codeigniter and i want to fetch recods as "two arrays"
based on condition (FilterType='Tag',FilterType='Merchant')
Here is my table "filterproducts"
id FilterType CategoryUrl
1 Tag abc
2 Tag xyz
3 Merchant abc
4 Merchant abc
Here is my current code which is giving me multidimenional array
function SearctRecords()
{
$this->db->select("*")
->from("filterproducts fp")
->join("filterid fi", "fp.FilterType=fi.name")
->where("fp.CategoryUrl", $CategoryUrl);
$query = $this->db->get();
$result = $query->result_array();
return $result;
}
Here is my controller
function SearchFilterProducts()
{
$users['data'] = $this->Customer_model->SearctRecords($CategoryUrl);
$responseJSON = array("Status" => $status, "data" => $users['data']);
header("content-type:application/json");
$response = json_encode($responseJSON);
echo $response;
}
I would recommend to sort using existing DB sorting methods. Usually will perform better than custom PHP function.
I you still want to sort your multidimensional result, consider using usort.
function custom_super_comparator($a, $b) {
//custom comparison
}
usort($response, "custom_super_comparator");
Check this good answer on this topic:
Sort array of objects by object fields
offtopic, SearctRecords is missing the argument
SearctRecords($CategoryUrl) {
I guys I am working diwth doctrine JOINS and I came across a problem.
I have done a query with joins and it seems ok, the results are good! but the output is terrible
public function getMarketcapData($page = -1, $limit = -1){
$pageAndCount = $page>-1 && $limit>0;
$qb = $this->getEntityManager()->createQueryBuilder();
$q = $qb->select('cc, count(cr) as coinRawsCount, cmc as relatedCategory')
->from('AppBundle:CoinClean', 'cc')
->leftJoin("AppBundle:CoinRaw", "cr", 'WITH', 'cc = cr.coinClean')
->leftJoin("AppBundle:CoinMapCategory", "cmc", 'WITH', 'cc.relatedCategory = cmc')
->andWhere('cc = cr.coinClean')
->andWhere('cc.relatedCategory = cmc')
->groupBy('cc.id')
;
if($pageAndCount) $q = $q->setFirstResult($page*$limit)->setMaxResults($limit);
$q= $q->orderBy('cc.rank', "ASC")->getQuery();
$result = $q->getResult();
if($pageAndCount){
$qb = $this->getEntityManager()->createQueryBuilder();
$q = $qb->select('count(u.id)')->from('AppBundle:CoinClean', 'u')->getQuery();
return new PageResult($result, (int)$q->getSingleScalarResult(), $page, $limit );
}else{
return $result;
}
}
here you have the output: it is an array made by array + obejcts
data:[
[ // first query result
{data from cc} // ony one object
],
{// first query result from join
"coinRawsCount": 4,
"relatedCategory": {...}
},
[ // second query result
{data from cc2} // ony one object
],
{// second query result from join
"coinRawsCount": 4,
"relatedCategory": {...}
}
]
my goal is to condense all in
"data":[
{
"data": {...},
"coinRawsCount": 4,
"relatedCategory": {...}
},
{
"data": {...},
"coinRawsCount": 4,
"relatedCategory": {...}
},
]
Any ideas?
You could loop over the result and merge on every other row, e.g. like this:
$rows = $q->getResult();
$result = []
foreach ($rows as $index => $row) {
if ($row instanceof App\Entity\CoinClean) {
// Skip first row and merge data when reading next row
continue;
}
$result[] = array_merge(
['data' => $rows[$index - 1]],
$row
);
}
return $result;
Assuming the first row is always the entity, we will skip this entry using continue;. The next row should contain an array with the additional data. We can then take the previous offset ($index - 1) to fetch the entry and the current row and merge them together. You might have to do additional checks.
Keep in mind that you will loop over a potentially large array and since you copy the data over to a new array this might use up a considerable amount of memory. So you might have to profile and optimize it, if you notice poor performance.
Other options would be to perform a native SQL query and then just map the output using a ResultSetMappingBuilder or to use custom hydration, i.e. create a new custom DTO-object for that query, that better fits the resulting data than the original entity structure, using DQL SELECT NEW App\Dto\MyModel FROM ...your query...'.
I'm trying to get Count of a table called TestRunList that has the foreign key the same as another table called Testrun meaning i want to get count of how many testrunlist that single testrun has in the same page i did a forloop to get testrun id for each testrunlist but it didn't seem to work i get this error
Cannot use object of type stdClass as array
heres my Code in the controller
$data = DB::table('TestRun')->get();
$runs=array();
for ($i=0;$i<sizeof($data);$i++)
{
$testrunID=$data[$i]['TestRunID'];
$Testrunlist=TestRunList::where('test_run_id',$testrunID)->count();
$runs[$i]=[
'Countruns'=>$Testrunlist
];
}
return view('management.testrun.testrun-list')
->with('data',$data)
->with('runs', $runs);
$data is a Collection, you can't access using array syntax
$data = DB::table('TestRun')->get();
$runs = [];
$data->each(function ($row) use ($runs) {
$runs[] = [
'Countruns' => TestRunList::where('test_run_id',$row-> TestRunID)->count()
];
});
return view('management.testrun.testrun-list')
->with('data',$data)
->with('runs', $runs);
Always use
print_r($data);
if it's object run echo $data->username if array run echo $data['username'];
So you know what type of data you're dealing with.
I have the following collection in Laravel:
["TheNumbers":[{"episodeID":16818,"episodeNumber":100,"created_at":null,"updated_at":null},{"episodeID":16818,"episodeNumber":210,"created_at":"2017-02-20 21:30:38","updated_at":"2017-02-20 21:30:38"}]
If I run the following code:
$TheEpisode->TheNumbers->pluck('episodeNumber');
I will get the following result:
[100,210]
I would like to keep the keys for each number, how can I achieve this?
EDIT: EXPECTED RESULT:
This is my expected result:
[{"episodeNumber":100},{"episodeNumber":210}]
PHILIS PETERS (improved)
TheEpisode->TheNumbers->reduce(function ($result, $episode) {
$episodeData = (collect())->put('episodeNumber', $episode['episodeNumber']);
$result[] = $episodeData;
return $result;
}));
Pluck() can take two params. The second of which is what the value can be keyed by.
You should be able to do:
$TheEpisode->TheNumbers->pluck('episodeNumber', 'episodeID');
Hope this helps!
Try something like this, it should work using map...
return $TheEpisode->TheNumbers->map(function ($episode) {
return ['episodeNumber' => $episode['episodeNumber']];
});
This can be simply achieved by passing a second argument to pluck. From the documentation:
You may also specify how you wish the resulting collection to be
keyed:
$plucked = $collection->pluck('name', 'product_id');
$plucked->all();
// ['prod-100' => 'Desk', 'prod-200' => 'Chair']
$collection->forget(['created_at', 'updated_at]);
This will simply left two first key-value pairs. Worth to keep in mind:
forget does not return a new modified collection; it modifies the collection it is called on.
Laravel docs
This should work properly:
$collection->only(['episodeID', 'episodeNumber']);
Try using
$TheEpisode->TheNumbers->lists('episodeNumber');
the key will remain.
Try using mapWithKeys like this:
$TheEpisode->TheNumbers->mapWithKeys(function ($theNumber) {
return ['episodeNumber' => $theNumber['episodeNumber']
});
I assume you want the result like this:
"TheNumbers":['episodeNumber':100,'episodeNumber':210]
For sake of updated Laravel, I tried all and I found
return Model::get(['name','id'])
will give reduced results with key => value.