SQL average of previous range of columns into current column - sql

I am trying to get the following calculations but at row level, in the image below I calculated the avg of values for each day (it can have n number of rows) then I used the LAG function to insert the avg of the previous row into the next row LAG_VAL column.
Now I am doing the calculations at row level, I have been able to get the average for that range of data using windowed functions (analytics)
ROUND(AVG(SUMCOUNTSFT3) OVER (partition by to_date(to_char(DATETIMEOFREADING, 'DD/MM/RRRR'))),2) as AVG_SUMCOUNTSFT3
but I have been not able to calculate the avg value of the previous day an insert that into the range of the next day as illustrated in the previous image.
Not sure if there is a way to implement this with the RANGE function of if I need to use PLSQL.

Off the top of my head (without a matching schema to test with) this windowing clause should work:
(partition by to_date(to_char(DATETIMEOFREADING, 'DD/MM/RRRR') order by dates range between interval '1' day preceding and interval '1' day preceding)
This is plain SQL, so it works inside as well as outside of PL/SQL.

Related

SQL LAG function

I tried using the LAG function to calculate the value of previous weeks, but there are gaps in the data due to the fact that certain weeks are missing.
This is the table:
The problem is that the LAG functions takes the previous found week in the table. But I would like it to be zero if the previous week is not consecutive previous week.
This is what I would like it to be:
I'm open to any solutions.
Thank you in advance
Your example data is baffling. You have multiple rows per time frame. The first column looks like a string, which doesn't really make sense for the comparison.
So, let me answer based on a simpler data mode. The answer is to use range. If you had an integer column that specified the time frame:
ordering sales
1 10
2 20
3 30
5 50
Then you would phrase this as:
select max(sales) over (order by ordering range between 1 preceding and 1 preceding)
This would return the value from the "previous" row as defined by the first column. The value would be in a separate column, not a separate row.

Number of days in a dataset SQL Oracle without GROUP by

Need to calculated the Moving Range for a set of data without using group by clause. As I am calculating the average value and the previous avg value I need to take into account only existing values. I cant not use DIFFDATE(start-end).
Another constrains is that I need to do it at row-level as I need to have it as a pre-calculated value (denominator) to calculate the AVG Moving Range.
At the moment I am using window functions to calculate the average and previous averages.
ROUND(AVG(SUMCOUNTSFT3) OVER (partition by to_date(to_char(DATETIMEOFREADING, 'DD/MM/RR'))),2) as AVG_SUMCOUNTSFT3,
ROUND(AVG(SUMCOUNTSFT3) OVER (order by to_date(to_char(DATETIMEOFREADING, 'DD/MM/RR')) RANGE between interval '1' day preceding AND interval '1' day preceding),2) as LAG_VAL
Here is some sample data, as you can see I have multiple readings from a sensor. I have calculated the average for that day and for the previous day. Then I will have the difference between data points by |Xi - Xi-1|, the denominator is the column that I am trying to calculate. In some cases we will not have reading for a day if the sensor is failing and I need to discard those days if there is no data.
I believe a ROW_NUMBER() or DENSE_RANK() will do the job with a partition clause.

Redshift - How to SUM number over last 4 weeks as a window function per row?

is it possible to SUM a number over a special time period in Amazon Redshift with a WINDOW-Function?
As an example I'm counting login numbers for different companies per day.
What I now want per row is, that it sums up the logins over the last 4 weeks (referenced by the date of the row): The field which I'm serarching for is marked yellow in the screenshot.
Thanks in advance for your help.
If you have data for each day, then you can use rows:
select t.*,
sum(logs) over (partition by company
order by date
rows between 27 preceding and current row
) as logins_4_weeks
from t;
Redshift does not yet support range for the window frame, so this is your best bet.

RANGE BETWEEN function with Timestamp values in SQL Impala

I am trying to calculate a moving number of events (impressions) that happen per minute. How can I use the range between function with timestamp values to define the 1-minute interval?
I have something like this:
count(impression) over (partition by user
ORDER BY trunc(cast(entrytime as TIMESTAMP), "MI")
RANGE BETWEEN interval 1 minutes Preceding
and interval 1 minutes Following) as densityperminute
but this doesn't seem to work. Any ideas on how to fix this?
I believe that's not supported, unfortunately. From the documentation for 6.1:
Currently, Impala supports only some combinations of arguments to the
RANGE clause:
RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW (the default when
ORDER BY is specified and the window clause is omitted)
RANGE BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING
RANGE BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING
Source
(Forgive me answering an old question, but I'm currently looking into this for a school project and this came up in my search!)

Running a complex loop query in PostgreSQL

I have one problem in PostgreSQL.
This is my table (this table does not showing all data in image).
What is my requirement is:
Step 1 : find count of value (this is a column in table) Order by value for today date. So it will be like this and I did it.
Step 2 : find count of value for last 30 days starting from today. I am stuck here. Also one another thing is included in this step --
Example : today has 10 count for a value - kash, this will be 10x30,
yesterday had 4 count for the same value , so will be 4x29, so the total sum would be
(10x30) + (4x29) = 416.
This calculation is calculated for each and every value.
This loop execute for 30 times (as I said before last 30 days starting from today). Take today as thirtieth day.
Query will just need to return two columns with value and sum, ordered by the sum.
Add a WHERE clause to your existing query:
WHERE Timestamp > current_date - interval '30' day;
As far as ordering by the sum, add an ORDER BY clause.
ORDER BY COUNT(*) DESC.
I do not believe that you will need a loop (CURSOR) for this query.