Laravel sum on ->first() sums more than 1 result - laravel

I have the following eloquent query
$raw = Model::select('out', 'in')->orderBy('created_at', 'DESC')->first();
That returns a collection of a single item, where Out = 0.0 and In = 90.0.
If I then do this:
$sumO = $raw->sum('out');
$sumI = $raw->sum('in');
I get $sumO = 13,651.41 and $sumI = 13371.69
I don't understand, because those sums don't even equal the sum of my entire table for those colums.
But it seems like->sum() is being called on the entire table/query instead of just the first result like I thought it would.
Now, I know sum of a single row is weird, and I'm not actually doing this in production. I just want to know what it is doing.
Shouldn't it still just sum the 1 number to equal itself?

It's just one row when using ->first(), so there's no need to use ->sum() just use $raw->in and $raw->out.
Also, ->sum() used with a single column at a time.

Related

Extract more rows from a left join with Laravel

I have to extract the rows where the created_at is inside the week. Unfortunately, only one line is extracted from me and no more lines as I expected. Why?
Query:
$scadenze = DB::table('processi')
->leftJoin('scadenze', 'processi.id', '=', 'scadenze.processo_id')
->where('responsabile',$utente->id)
->whereNotIn('scadenze.stato', [4,5])
->whereBetween('scadenze.termine_stimato',[\Carbon::now()->startOfWeek(), Carbon::now()->endOfWeek()])
->avg('tempistica');
This query extract just one row, but in reality many more lines should be extracted.
Because ->avg('tempistica'); return average value from all your rows in this query, i.e. return just one value.
Solution:
I was wrong to use the avg with sum function. The rows were extracted correctly but instead of being added (by timing) an average was made. Thank you all for your help.

Ruby on Rails: Active-Record sort and put specific row to the top

I have an Active record one -> many association and I need to get all child rows starting with a specific row
something like
parent.children.startwith(some_child_row_id)
Is there a one-liner?
Edit:
For more Clarity
Let say we have an array
a = ["a","b" ,"cg", "d","e"]
I want "cg" to be first element.
I'll do somthing like
element = a.delete("cg") // array will be ["a","b","d","e"]
a.unshift(element) // array will now become ["cg","a","b","d","e"]
See! An element is moved to index 0.
I want the same in case of ActiveRecord rows, Preferably a One-liner.
I suppose conditional ordering will do the trick.
parent.children.order("CASE WHEN (id = #{some_child_row_id}) THEN 0 ELSE 1 END ASC, id")
It's pretty simple actually.
All you need is to apply a where clause to the children of your parent.
Try something like this.
parent.children.where('id > ?', start_row)
I believe this is what you were looking for. Hope this helps.

laravel ->count() vs ->get()->count()

Why are the two statement below behaving differentlY? The first returns 3 the second returns 1 for $progress. I thought that the first aggregates on the DB and the second on the server. So they should still return the same value.
$progress = $this->user->userActivities()->select('date')
->groupBy('date')
->get()->count();
$progress = $this->user->userActivities()->select('date')
->groupBy('date')
->count();
->get()->count() will load Eloquent model objects into memory and then will count those.
->count() will use DB aggregate function, so it will definitely be more efficient:
select count(*) as aggregate ...
It's quite late answer but I had faced the same issue. These two examples are returning two different counts because of groupBy you have used.
$progress = $this->user->userActivities()->select('date')
->groupBy('date')
->get()->count();
This takes the rows first, then count the row numbers and returns the count.
$progress = $this->user->userActivities()->select('date')
->groupBy('date')
->count();
Whereas this counts the rows by its group in the DB and returns the first group's row record count only from the list.
the solution I used instead of get()->count() for my case is like
$progress = $this->user->userActivities()
->distinct('date')
->count('date');
Use ->get()->count() is wrong. I used ->get()->count() in my web app and when my database records have more than 80000 records I get error 500 in my app.
The first counts the number of returned records, the second counts the records and returns the number. If you are using a paging of 10, for example, then the first will yield 10 and the second the actual number if the number of mathcing elements is greater than 10.
$count = Model::all()->count();
return view('home',compact('count'));
this will function for laravel 6;
Both of them return the same result. But as said for preventing to crash or decrease the speed of response it's better to use count() instead of get()->count()

How to filter clickhouse table by array column contents?

I have a clickhouse table that has one Array(UInt16) column. I want to be able to filter results from this table to only get rows where the values in the array column are above a threshold value. I've been trying to achieve this using some of the array functions (arrayFilter and arrayExists) but I'm not familiar enough with the SQL/Clickhouse query syntax to get this working.
I've created the table using:
CREATE TABLE IF NOT EXISTS ArrayTest (
date Date,
sessionSecond UInt16,
distance Array(UInt16)
) Engine = MergeTree(date, (date, sessionSecond), 8192);
Where the distance values will be distances from a certain point at a certain amount of seconds (sessionSecond) after the date. I've added some sample values so the table looks like the following:
Now I want to get all rows which contain distances greater than 7. I found the array operators documentation here and tried the arrayExists function but it's not working how I'd expect. From the documentation, it says that this function "Returns 1 if there is at least one element in 'arr' for which 'func' returns something other than 0. Otherwise, it returns 0". But when I run the query below I get three zeros returned where I should get a 0 and two ones:
SELECT arrayExists(
val -> val > 7,
arrayEnumerate(distance))
FROM ArrayTest;
Eventually I want to perform this select and then join it with the table contents to only return rows that have an exists = 1 but I need this first step to work before that. Am I using the arrayExists wrong? What I found more confusing is that when I change the comparison value to 2 I get all 1s back. Can this kind of filtering be achieved using the array functions?
Thanks
You can use arrayExists in the WHERE clause.
SELECT *
FROM ArrayTest
WHERE arrayExists(x -> x > 7, distance) = 1;
Another way is to use ARRAY JOIN, if you need to know which values is greater than 7:
SELECT d, distance, sessionSecond
FROM ArrayTest
ARRAY JOIN distance as d
WHERE d > 7
I think the reason why you get 3 zeros is that arrayEnumerate enumerates over the array indexes not array values, and since none of your rows have more than 7 elements arrayEnumerates results in 0 for all the rows.
To make this work,
SELECT arrayExists(
val -> distance[val] > 7,
arrayEnumerate(distance))
FROM ArrayTest;

Sum Formula Crystal Reports Inquiry

Ok, say I have a subreport that populates a chart I have from data in a table. I have a summary sum field that adds up the total of each row displayed. I am about to add two new rows that need to be displayed but not totaled up in the sum. There is a field in the table that has a number from 1-7 in it. If I added these new fields into the database, I would assign a negative number to this like -1 and -2 to differentiate it between the other records. How can I set up a formula so that it will sum up all of the amount fields except for the records that have an 'order' number we will call it of either -1 or -2? Thanks!
Use a Running Total Field and set the evaluate formula to something like {new_field} >= 0. So it will only sum the value when it passes that test.
The way to accomplish this without a running total is with a formula like this:
if {OrderNum} >= 0 Then {Amount}

Resources