SSRS sum values based on row number - sql

I would like to get the sum of all values in a column IF they have a rowNumber greater than the current row
so if i have 4 rows:
Row 1 would be the sum of rows 2,3 and 4
Row 2 would be the sum of rows 3 and 4
Row 3 would be the value of row 4
Row 4 would be 0
This is the query I currently have:
SELECT
no_,
name AS member,
amount,
effective,
balance
FROM c
WHERE
status != 'closed'
AND amount != 0.00
ORDER BY no_, effective
In my ssrs table I'm using the expression RowNumber("member") to assign row numbers for each row per member

You would seem to want a cumulative sum in reverse order, excluding the current value. I would express this as:
select sum(val) over (order by rownum desc) - val
I am clear how this relates to your query.
You can also express this using a window frame:
select sum(val) over (order by rownum rows between 1 following and unlimited following)
The only difference is that this would return NULL for the last row rather than 0.

Related

Partition Over Clause with start and stop

I have a set of data where value is calculated starting from 1 - 12 then moves 1 step down and calculates another 1 - 12. This works well in Excel however how do I achieve this in SQL.
Is it even possible?
I have tried
ROW_COUNT = ROW_NUMBER()OVER(PARTITION BY StudioMain ORDER BY Finperiod ASC)/13+1,
which gives me a list of numbers then restarts after 12
so I want to sum rows 1-12 then I want to sum rows 1-12 but starting at row 2 ending at row 13
then sum rows 1-12 starting at row 3 ending at row 14
How do I sum row 1 12 then restart sum 1-12 but from row 2?
It looks like you want a window sum with a row frame:
select
t.*,
Debtors / sum(GrossSales) over(
partition by StudioMain
order by Finperiod
rows between 11 preceding and current row
) DeptorDays
from mytable t
order by StudioMain, FinPeriod
If you want no results for the 11 first rows, as shown in your image, you can wrap the sum() in a conditional expression:
select
t.*,
case when row_number() over(partition by StudioMain order by Finperiod) >= 12
then Debtors / sum(GrossSales) over(
partition by StudioMain
order by Finperiod
rows between 11 preceding and current row
)
end DeptorDays
from mytable t
order by StudioMain, FinPeriod

Find Nearest rows in SQL

I have table with 2 records and column name quantity.
quantity
2268
22680
so,
when my required quantity 2500 then i want to display both 2 records
when my required quantity 2000 then display 1st row.
You seem to want a cumulative sum. The ANSI standard method would be:
select t.*
from (select t.*, sum(quantity) over (order by ?) as cume_quantity
from t
) t
where cume_quantity - quantity <= <your value here>;
The ? is for the column or expression that specifies the ordering of the rows.

Find average in postgresql

In my table I am having say 5 numbers. I want to find moving average of 3 numbers.
Query I am using is
select avg(value) over(order by value rows between 3 preceding and 1 preceding) as average
from test;
I want my query to start finding average from 4th value as first three values will not be having 3 previous values to calculate from. Please suggest.
The average will work for the first three -- it will just either be NULL or based on fewer than 3 rows.
But, you can do what you want using row_number();
select (case when row_number() over (order by value) > 3
then avg(value) over (order by value rows between 3 preceding and 1 preceding)
end) as average
from test;

SQL select top rows based on limit

Please help me t make below select query
Source table
name Amount
-----------
A 2
B 3
C 2
D 7
if limit is 5 then result table should be
name Amount
-----------
A 2
B 3
if limit is 8 then result table
name Amount
-----------
A 2
B 3
C 2
You can use window function to achieve this:
select name,
amount
from (
select t.*,
sum(amount) over (
order by name
) s
from your_table t
) t
where s <= 8;
The analytic function sum will be aggregated row-by-row based on the given order order by name.
Once you found sum till given row using this, you can filter the result using a simple where clause to find rows till which sum of amount is under or equal to the given limit.
More on this topic:
The SQL OVER() clause - when and why is it useful?
https://explainextended.com/2009/03/08/analytic-functions-sum-avg-row_number/

T-SQL calculate moving average

I am working with SQL Server 2008 R2, trying to calculate a moving average. For each record in my view, I would like to collect the values of the 250 previous records, and then calculate the average for this selection.
My view columns are as follows:
TransactionID | TimeStamp | Value | MovAvg
----------------------------------------------------
1 | 01.09.2014 10:00:12 | 5 |
2 | 01.09.2014 10:05:34 | 3 |
...
300 | 03.09.2014 09:00:23 | 4 |
TransactionID is unique. For each TransactionID, I would like to calculate the average for column value, over previous 250 records. So for TransactionID 300, collect all values from previous 250 rows (view is sorted descending by TransactionID) and then in column MovAvg write the result of the average of these values. I am looking to collect data within a range of records.
The window functions in SQL 2008 are rather limited compared to later versions and if I remember correct you can only partition and you can't use any rows/range frame limit but I think this might be what you want:
;WITH cte (rn, transactionid, value) AS (
SELECT
rn = ROW_NUMBER() OVER (ORDER BY transactionid),
transactionid,
value
FROM your_table
)
SELECT
transactionid,
value,
movagv = (
SELECT AVG(value)
FROM cte AS inner_ref
-- average is calculated for 250 previous to current row inclusive
-- I might have set the limit one row to large, maybe it should be 249
WHERE inner_ref.rn BETWEEN outer_ref.rn-250 AND outer_ref.rn
)
FROM cte AS outer_ref
Note that it applies a correlated sub-query to every row and performance might not be great.
With the later versions you could have used window frame functions and done something like this:
SELECT
transactionid,
value,
-- avg over the 250 rows counting from the previous row
AVG(value) OVER (ORDER BY transactionid
ROWS BETWEEN 251 PRECEDING AND 1 PRECEDING),
-- or 250 rows counting from current
AVG(value) OVER (ORDER BY transactionid
ROWS BETWEEN 250 PRECEDING AND CURRENT ROW)
FROM your_table
Use a Common Table Expression (CTE) to include the rownum for each transaction, then join the CTE against itself on the row number so you can get the previous values to calculate the average with.
CREATE TABLE MyTable (TransactionId INT, Value INT)
;with Data as
(
SELECT TransactionId,
Value,
ROW_NUMBER() OVER (ORDER BY TransactionId ASC) as rownum
FROM MyTable
)
SELECT d.TransactionId , Avg(h.Value) as MovingAverage
FROM Data d
JOIN Data h on h.rownum between d.rownum-250 and d.rownum-1
GROUP BY d.TransactionId