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

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'
},
...
]

Related

Laravel - Groupby and merge the other column

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

ActiveQuery count() and all() return different results

I have a query:
$query = Products::find();
$query->joinWith('vendor', true, 'LEFT JOIN');
$query->joinWith('values', true,'LEFT JOIN');
$query->where(['<>', 'stock', 7]);
$query->andWhere(['category_id' => $model->id]);
if (!empty($activeVendors))
$query->andWhere(['lan_vendors.id' => array_flip($activeVendors)]);
if (!empty($activeValues)){
$query->andWhere(['lan_products_values.value_id' => $activeValues]);
}
$totalProducts = $query->count();
$products = $query->all();
In result:
$totalProducts = 12;
count($products) = 3;
I can not solve this problem. Reading the documentation did not help. Is there something wrong with the database itself?
your left join statements generate duplicate rows.
after a the query runs yii removes duplicate data and creates a usable array of uniqe Product models
the duplicate rows are not avoidable in your case since you enforce eager loading with left join
$query->joinWith('vendor', true, 'LEFT JOIN');
$query->joinWith('values', true,'LEFT JOIN');
you can try to run something like this to adjust the relations to your conditions, and follow the generated queries
in the debug log,
$query->with([
'vendor' => function (\yii\db\ActiveQuery $query) use ($activeVendors) {
$query->andFilterWhere(['lan_vendors.id' => array_flip($activeVendors)]);
},
'values' => function (\yii\db\ActiveQuery $query) use ($activeValues) {
$query->andWhere(['lan_products_values.value_id' => $activeValues]);
},
])
also follow the generated queries in the debug log, it's a usefull way of figuring out what happens in the two cases
Because you are joining additional tables here most probably you have got dupicated results - you can check it by running this query manually outside of Yii.
Query count() is showing you all the rows fetched from database (with duplicates).
all() on the other hand takes the fetched rows and while populating the Yii 2 models it removes duplicates so you have got unique ones.

Laravel Query Builder: MySQL 'LIKE' inside a multiple where conditioned query

Im trying to do a query where i have multiple conditions (including %LIKE% operator) but can't figure how to do it in Laravel's array way with query builder.
$where = ['category' => $c->id, 'name' => $c->name];
$q = Store::where($where)->get();
That way it would return an array of objects with the equal of the name, not the similar matches. Is it possible to do a %LIKE% search in that way?
You should chain them like this:
DB::table('your-table-name')
->where('category','=','$c->id')
->where('name','=','$c->name')
->where('email', 'LIKE', '%test%')
->get();

How can I build a condition based query in Laravel using eloquent

I was wondering how can I build a condition based query in Laravel using eloquent?
I've found how to do it with a raw query but that that's not what I want also the answer to this question isn't that dynamic at least not as dynamic as I want it to be.
What I try to achieve is to create a dynamic WHERE query based on certain conditions, for example if the field is filled or not.
If I use the following code,
$matchThese = [
'role' => 'user',
'place' => \Input::get('location')
];
$availableUsers = User::where($matchThese)->take($count)->orderByRaw("RAND()")->get();
The query will fail if I don't send a location as POST value. I don't want it to fail I want it to skip to the next WHERE clause in the query. So basically if there's no place given don't search for it.
Build up the query and include the ->where() clause depending on whether or not you have the location in your input:
$query = User::where('role', 'user');
$query = \Input::has('location') ? $query->where('location', \Input::get('location')) : $query;
$availableUsers = $query->take($count)->orderByRaw('RAND()')->get();
Just build the array with an if condition:
$matchThese = [
'role' => 'user',
];
if(\Input::has('location')){
$matchThese['place'] = \Input::get('location');
}
$availableUsers = User::where($matchThese)->take($count)->orderByRaw("RAND()")->get();
$query = DB::table('table_name');
if($something == "something"){
$query->where('something', 'something');
}
$some_variable= $query->where('published', 1)->get();
You can use something like this.

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]);

Categories