I want to add an average cost column which calculates the average across different time periods.
So in the example below, there are 6 months of cost, the first column finds the average across all 6 i.e. average(1,5,8,12,15,20)
The next "Half Period" column determines how many total periods there are and calculates the average across the most recent 3 periods i.e. average(12,15,20)
The first average is straightforward e.g.
AVG(COST)
What I've tried for the half period is:
AVG(COST) OVER (ORDER BY PERIOD ROWS BETWEEN x PRECEDING AND CURRENT ROW)
The x is of course an integer value, how would I write the statement to automatically enter the integer required? i.e. in this example 6 periods requires 3 rows averaged, therefore x=2.
x can be found by some sub-query e.g.
SELECT ( CEILING(COUNT(PERIOD) / 2) - 1) FROM TABLE
Example table:
| Period | Cost |
| ------------ | ------------ |
| Jan | 1 |
| Feb | 5 |
| Mar | 8 |
| Apr | 12 |
| May | 15 |
| Jun | 20 |
Desired Output:
| Period | Cost | All Time Average Cost | Half Period Average Cost |
| ------------ | ------------ | ------------ | ------------ |
| Jan | 1 | 10.1 | 1 |
| Feb | 5 | 10.1 | 3 |
| Mar | 8 | 10.1 | 4.7 |
| Apr | 12 | 10.1 | 8.3 |
| May | 15 | 10.1 | 11.7 |
| Jun | 20 | 10.1 | 15.7 |
3条答案
按热度按时间rvpgvaaj1#
The main problem here is that you cannot use a variable or an expression for the number of rows Preceeding in the window expression, we must use a literal value for
x
in the following:BETWEEN x PRECEDING
If there is a finite number of periods, then we can use a
CASE
statement to switch between the possible expressions:s4n0splo2#
我在SQL中添加了这个步骤。但是我的窗口函数拒绝接受变量half_period_rounded。所以我们还没有完全做到这一点。:-)
SQL query
euoag5mw3#
This looks like a job for sneaky windowed function aggregates!
We're cheating here, and having the case expression find the rows we want in our rolling 3 month window. I've opted to keep it to a rolling window of last month, this month and next month (from the first day of last month, to the last day of next month - '2022-01-01 00:00:00' to '2022-04-01 00:00:00' for February).
Partitioning over the whole result set, month and quarter is straightforward, but the rolling three months isn't much more complicated when you turn it into a case expression describing it.