SQL Server 2012 Windowing function to calculate a running total - sql

I need some help with windowing functions.
I have been playing around with sql 2012 windowing functions recently. I know that you can calculate the sum within a window and the running total within a window. But i was wondering; is it possible to calculate the previous running total i.e. the running total not including the current row ? I assume you would need to use the ROW or RANGE argument and I know there is a CURRENT ROW option but I would need a CURRENT ROW - I which is invalid syntax. My knowledge of the ROW and RANGE arguments is limited so any help would be gratefully received.
I know that there are many solutions to this problem, but I am looking to understand the ROW, RANGE arguments and I assume the problem can be cracked with these. I have included one possible way to calculate the previous running total but I wonder if there is a better way.
USE AdventureWorks2012
SELECT s.SalesOrderID
, s.SalesOrderDetailID
, s.OrderQty
, SUM(s.OrderQty) OVER (PARTITION BY SalesOrderID) AS RunningTotal
, SUM(s.OrderQty) OVER (PARTITION BY SalesOrderID
ORDER BY SalesOrderDetailID) - s.OrderQty AS PreviousRunningTotal
-- Sudo code - I know this does not work
--, SUM(s.OrderQty) OVER (PARTITION BY SalesOrderID
-- ORDER BY SalesOrderDetailID
-- ROWS BETWEEN UNBOUNDED PRECEDING
-- AND CURRENT ROW - 1)
-- AS SudoCodePreviousRunningTotal
FROM Sales.SalesOrderDetail s
WHERE SalesOrderID IN (43670, 43669, 43667, 43663)
ORDER BY s.SalesOrderID
, s.SalesOrderDetailID
, s.OrderQty
Thanks in advance

You could subtract the current row's value:
SUM(s.OrderQty) OVER (PARTITION BY SalesOrderID
ORDER BY SalesOrderDetailID) - s.OrderQty
Or according to the syntax at MSDN and ypercube's answer:
<window frame preceding> ::=
{
UNBOUNDED PRECEDING
| <unsigned_value_specification> PRECEDING
| CURRENT ROW
}
-->
SUM(s.OrderQty) OVER (PARTITION BY SalesOrderID
ORDER BY SalesOrderDetailID
ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING)

Related

how to use current row data in a condition inside a window function on a partition with range between unbounded preceding and current row

I need to use the current row values in a condition used in a window function on a partition with range. See my example query I am looking for.
select
count(case when orderdate >=
(**current_row.orderdate** -30) then 1 end)
over (partition by customerid order by orderdate range between unbounded preceding and current row)
from xyz
Not getting correct syntax.
Please see below example output required. This is just an example, the 30 days and the logic is just a sample.

Create a column with lagging running total

I have a table like below:
From values, I can easily get to cum_values using window function:
sum(values) over (order by id ASC rows between unbounded preceding and current row) as cum_values
How do I get cum_values_minus1, I tried a few iterations using "rows between", but they aren't working!
Any help is appreciated.

How to get correct cumulative balance?

I have this simple query
select ArticleID, Prix, Qte, InfStock
, SUM(Qte*InfStock) OVER (Partition BY ArticleID ORDER BY DateDocument) AS CUMUL
FROM Balance
Please look the result (Line 4)
Here is the backup file(zipped)
You need to add to the end of the OVER clause ROWS UNBOUNDED PRECEDING.
SUM defaults to RANGE UNBOUNDED PRECEDING which can cause issues like this.
See here for example, for further explanation.

Is there a way to calculate percentile using percentile_cont() function over a rolling window in Big Query?

I have a dataset with the following columns
city
user
week
month
earnings
Ideally I want to calculate a 50th % from percentile_cont(earnings,0.5) over (partition by city order by month range between 1 preceding and current row). But Big query doesn't support window framing in percentile_cont. Can anyone please help me if there is a work around this problem.
If I understand correctly, you can aggregate into an array and then unnest:
select t.*,
(select percentile_cont(earning) over ()
from unnest(ar_earnings) earning
limit 1
) as median_2months
from (select t.*,
array_agg(earnings) over (partition by city
order by month
range between 1 preceding and current month
) as ar_earnings
from t
) t;
You don't provide sample data, but this version assumes that month is an incrementing integer that represents the month. You may need to adjust the range depending on the type.

Netezza SQL: Specify an offset in a window frame

When making the "frame" for a windowed analytic function, one can specify a literal number of rows to "look back" over. E.g., the following will get the trailing 26 weeks weekly sales for a households.
,sum(sales) over (partition by household_id order by week_id rows 26 preceding) as x26
But... what if you wanted to look back (or forward) with an offset? E.g., if for week n, you wanted the sales for the 26 weeks that ended 8 weeks before week n? As I was typing this, it occurred to me that I could probably do it in parts. I.e.,
,sum(sales) over (partition by household_id order by week_id rows 34 preceding) as x34
,sum(sales) over (partition by household_id order by week_id rows 8 preceding) as x8
...and have trailing26_offeset8 = x34 - x8
Hm... Glad I asked. But anyway, do you know if there's an feature that will let me specify the offset right in the partition specification itself?
Thanks!
Try using between in the window range specification:
sum(sales) over (partition by household_id
order by week_id
rows between 34 preceding and 8 preceding
) as x34