Laravel Eloquent: sum with groupBy - sql

Need eloquent/fluent query to get sum with groupBy function.
So far I have tried:
$this->data['no_of_pages'] = Document::sum('no_of_pages')
->groupBy('users_editor_id');
Which ofcourse gives me call to member function groupBy() on non-object because of the fact that sum() will already execute the query and have result ready by the time grouBy() is applied. So can anyone guide me?

Document::groupBy('users_editor_id')
->selectRaw('sum(no_of_pages) as sum, users_editor_id')
->pluck('sum','users_editor_id');
// originally lists(), which was deprecated in favour of pluck in 5.2
// and dropped completely in 5.3
// ->lists('sum','users_editor_id');
// returns array like this:
array(
users_editor_id => sum,
...
)
Or this way (which I wouldn't use, since it won't be actual ORM result):
Document::groupBy('users_editor_id')
->selectRaw('*, sum(no_of_pages) as sum')
->get();
// returns collection of Document pseudo models with additional sum field

Document::Where('some_condition',true)
->select([DB::raw("SUM(debit) as total_debit"), DB::raw("SUM(credit) as total_credit")])
->groupBy('id')
->get()

Little bit refactored and convenient answer is (from #keroles Monsef)
Document::Where('some_condition',true)
->selectRaw("SUM(debit) as total_debit")
->selectRaw("SUM(credit) as total_credit")
->groupBy('id')
->get();

Related

CodeIgniter4 Model returning data results

I am starting to dabble in CI4's rc... trying to get a head of the game. I noticed that the Model is completely rewritten.
Going through their documentation, I need some guidance on how to initiate the equivalent DB query builder in CI4.
I was able to leverage return $this->findAll(), etc...
however, need to be able to be able to query w/ complex joins and also be able to return single records etc...
When trying something like
return $this->orderBy('import_date', 'desc')
->findColumn('import_date')
->first();
but getting error:
Call to a member function first() on array
Any help or guidance is appreciated.
Suppose you have a model instantiated as
$userModel = new \App\Models\UserModel;
Now you can use it to get a query builder like.
$builder = $userModel->builder();
Use this builder to query anything for e.g.
$user = $builder->first();
Coming to your error.
return $this->orderBy('import_date', 'desc')
->findColumn('import_date');
findColumn always returns an array or null. So you can't use it as object. Instead you should do following.
return $this->orderBy('import_date', 'desc')->first();

orderby doesn't work in Laravel Eloquent advanced query

I'd like to sort my data by using orderby in Laravel Eloquent advanced query. Here is my code:
$users = User::where(function($query){
$query->orderBy('created_at', 'DESC');
})->get()->toArray();
var_dump($users);
But it doesn't work. Instead if I use orderby like this:
$users = User::orderBy('created_at', 'DESC')->get()->toArray();
var_dump($users);
It works.
Can anybody suggest how to make the orderby works for the advanced query? Thanks
I tried all sorts of different combinations and found the orderBy must be outside the query function (or maybe should be the last one?). Here is the code which is working:
$users = User::where(function($query){
// ......
})->orderBy('created_at', 'DESC')->get()->toArray();
var_dump($users);

How do I get the results of the Plucky Query inside my controller?

I'm missing something simple - I do not want to access the results of this query in a view.
Here is the query:
#adm = Admin.where({:id => {"$ne" => params[:id].to_s},:email => params[:email]})
And of course when you inspect you get:
#adm is #<MongoMapper::Plugins::Querying::DecoratedPluckyQuery:0x007fb4be99acd0>
I understand (from asking the MM guys) why this is the case - they wished to delay the results of the actual query as long as possible, and only get a representation of the query object until we render (in a view!).
But what I'm trying to ascertain in my code is IF one of my params matches or doesn't match the result of my query in the controller so I can either return an error message or proceed.
Normally in a view I'm going to do:
#adm.id
To get the BSON out of this. When you try this on the Decorated Query of course it fails:
NoMethodError (undefined method `id' for #<MongoMapper::Plugins::Querying::DecoratedPluckyQuery:0x007fb4b9e9f118>)
This is because it's not actually a Ruby Object yet, it's still the query proxy.
Now I'm fundamentally missing something because I never read a "getting started with Ruby" guide - I just smashed my way in here and learned through brute-force. So, what method do I call to get the results of the Plucky Query?
The field #adm is set to a query as you've seen. So, to access the results, you'll need to trigger execution of the query. There are a variety of activation methods you can call, including all, first, and last. There's a little documentation here.
In this case, you could do something like:
adm_query = Admin.where({:id => {"$ne" => params[:id].to_s},:email => params[:email]})
#adm_user = adm_query.first
That would return you the first user and after checking for nil
if #adm_user.nil?
# do something if no results were found
end
You could also limit the query results:
adm_query = Admin.where( ... your query ...).limit(1)

Order by record count on sub collection

I am trying to convert some old code to use Fluent Nhibernate.
Old code:
allOrders.OrderBy(x => x.OrdersLineItems.Count);
How do I convert it to something like:
query.AddOrder(new Order(????, true));
Is this even possible?
Thanks in advance
UPDATE:
Here is the simplified code I am trying to write:
ICriteria query = FluentSessionManager.GetSession().CreateCriteria<Orders>()
.AddOrder(new Order(????, true));
The joined table is OrdersLineItems. I need to set the order by the count of the line items. Since I am using paging with a data set that has over 500,000 records, simply pulling all the records into memory and then sorting them will not.
Thanks in advance.
ICriteria query = FluentSessionManager.GetSession().CreateCriteria<Orders>()
.CreateAlias("this.OrderLineItems", "oli")
.AddOrder(new Order(Projections.Count("oli.Id"), true));
Something like that I should think. It's probably not perfect but at least illustrates that you need to use Projections.Count to get it done.

dojo query for multiple values with setQuery

I'm having trouble getting the syntax right for a setQuery method call for multiple values, i.e.
setQuery({x : 1}) or setQuery({x : 2})
combined. Or do I need to use filter?
In case you are using Dojo Store API I think one way to query using function is described here
You can modify it like this
store.query(function(item){
return item.x == 1 || item.x == 2;
});
That will depend on the store you are using.
In order to do that easier, you should use dojox.data.AndOrReadStore
Dojo tool kit, and or read store
using that store you can use setQuery as:
yourgrid.setQuery({complexQuery:"x:1 OR x:2"});