Function table / Table calculations / Difference from last period

Difference from last period, from Tableau to SQL

Subtracts the revenue of the last addressed period in each region. Below, 8 sample rows go through the calculation and through the SQL, and both return the same numbers.

Calculated field

SUM([Revenue]) - LOOKUP(SUM([Revenue]), LAST())

Compute using: addressing Period; partitioning Region

Sample data

RegionPeriodRevenueCost
Harbor112070
Harbor2180100
Harbor3180120
Harbor4240140
Upland19050
Upland2150110
Upland3null90
Upland4330190

The same calculation as SQL

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

Runs the example above.

Result

RegionPeriodRevenueCostresult
Harbor112070-120
Harbor2180100-60
Harbor3180120-60
Harbor42401400
Upland19050-240
Upland2150110-180
Upland3null90null
Upland43301900

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(("Revenue" - last_value("Revenue") OVER ( ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS DOUBLE) AS result FROM input ORDER BY "Region", "Period"
    RegionPeriodRevenueCostresult
    Harbor112070-210
    Harbor2180100-150
    Harbor3180120-150
    Harbor4240140-90
    Upland19050-240
    Upland2150110-180
    Upland3null90null
    Upland43301900

    Matches the calculation

    SELECT CAST(("Revenue" - last_value("Revenue") OVER (PARTITION BY "Region" ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)) AS DOUBLE) AS result FROM input ORDER BY "Region", "Period"
    RegionPeriodRevenueCostresult
    Harbor112070-120
    Harbor2180100-60
    Harbor3180120-60
    Harbor42401400
    Upland19050-240
    Upland2150110-180
    Upland3null90null
    Upland43301900

Signature

SUM([Revenue]) - LOOKUP(SUM([Revenue]), LAST())