Function table / Table calculations / Running revenue product

Running revenue product, from Tableau to SQL

Multiplies each revenue into the prior calculated product; a null propagates. Below, 8 sample rows go through the calculation and through the SQL, and both return the same numbers.

Calculated field

SUM([Revenue]) * PREVIOUS_VALUE(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((CASE WHEN count(*) OVER (PARTITION BY "Region" ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) != count("Revenue") OVER (PARTITION BY "Region" ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) THEN NULL ELSE product("Revenue") OVER (PARTITION BY "Region" ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) END) AS DOUBLE) AS result FROM input ORDER BY "Region", "Period"

Runs the example above.

Result

RegionPeriodRevenueCostresult
Harbor112070120
Harbor218010021600
Harbor31801203888000
Harbor4240140933120000
Upland1905090
Upland215011013500
Upland3null90null
Upland4330190null

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((CASE WHEN count(*) OVER ( ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) != count("Revenue") OVER ( ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) THEN NULL ELSE product("Revenue") OVER ( ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) END) AS DOUBLE) AS result FROM input ORDER BY "Region", "Period"
    RegionPeriodRevenueCostresult
    Harbor112070120
    Harbor21801001944000
    Harbor318012052488000000
    Harbor4240140null
    Upland1905010800
    Upland2150110291600000
    Upland3null90null
    Upland4330190null

    Matches the calculation

    SELECT CAST((CASE WHEN count(*) OVER (PARTITION BY "Region" ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) != count("Revenue") OVER (PARTITION BY "Region" ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) THEN NULL ELSE product("Revenue") OVER (PARTITION BY "Region" ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) END) AS DOUBLE) AS result FROM input ORDER BY "Region", "Period"
    RegionPeriodRevenueCostresult
    Harbor112070120
    Harbor218010021600
    Harbor31801203888000
    Harbor4240140933120000
    Upland1905090
    Upland215011013500
    Upland3null90null
    Upland4330190null

Signature

SUM([Revenue]) * PREVIOUS_VALUE(1)