Function table / Table calculations / Centered three-period average

Centered three-period average, from Tableau to SQL

Averages the previous, current, and next regional marks with clipped edges. Below, 8 sample rows go through the calculation and through the SQL, and both return the same numbers.

Calculated field

WINDOW_AVG(SUM([Revenue]), -1, 1)

Compute using: addressing Period; partitioning Region

Sample data

RegionPeriodRevenueCost
Harbor112070
Harbor2180100
Harbor3180120
Harbor4240140
Upland19050
Upland2150110
Upland3null90
Upland4330190

The same calculation as SQL

SELECT CAST((avg("Revenue") OVER (PARTITION BY "Region" ORDER BY "Period" ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)) AS DOUBLE) AS result FROM input ORDER BY "Region", "Period"

Runs the example above.

Result

RegionPeriodRevenueCostresult
Harbor112070150
Harbor2180100160
Harbor3180120200
Harbor4240140210
Upland19050120
Upland2150110120
Upland3null90240
Upland4330190330

Same rows from the calculation and from the SQL in DuckDB.

Where a naive translation goes wrong

  • An unpartitioned SQL window mixes independent regional calculation sequences.

    Naive SQL

    SELECT CAST((avg("Revenue") OVER ( ORDER BY "Period" ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)) AS DOUBLE) AS result FROM input ORDER BY "Region", "Period"
    RegionPeriodRevenueCostresult
    Harbor112070105
    Harbor2180100140
    Harbor3180120165
    Harbor4240140285
    Upland19050130
    Upland2150110170
    Upland3null90210
    Upland4330190285

    Matches the calculation

    SELECT CAST((avg("Revenue") OVER (PARTITION BY "Region" ORDER BY "Period" ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING)) AS DOUBLE) AS result FROM input ORDER BY "Region", "Period"
    RegionPeriodRevenueCostresult
    Harbor112070150
    Harbor2180100160
    Harbor3180120200
    Harbor4240140210
    Upland19050120
    Upland2150110120
    Upland3null90240
    Upland4330190330

Signature

WINDOW_AVG(SUM([Revenue]), -1, 1)