RUNNING_STDEV: from Tableau to SQL

Calculates stdev over the current and preceding regional marks, excluding null revenues. Below, 8 sample rows go through the calculation and through the SQL, and both return the same numbers.

Calculated field

RUNNING_STDEV(SUM([Revenue]))

Compute using: addressing Period; partitioning Region

Sample data

RegionPeriodRevenueCost
Harbor112070
Harbor2180100
Harbor3180120
Harbor4240140
Upland19050
Upland2150110
Upland3null90
Upland4330190

The same calculation as SQL

SELECT CAST((stddev_samp("Revenue") OVER (PARTITION BY "Region" ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) AS DOUBLE) AS result FROM input ORDER BY "Region", "Period"

Runs the example above.

Result

RegionPeriodRevenueCostresult
Harbor112070null
Harbor218010042.4264
Harbor318012034.641
Harbor424014048.9898
Upland19050null
Upland215011042.4264
Upland3null9042.4264
Upland4330190124.9

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

Where a naive translation goes wrong

  • Omitting the region partition allows a calculation to consume marks from other regions.

    Naive SQL

    SELECT CAST((stddev_samp("Revenue") OVER ( ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) AS DOUBLE) AS result FROM input ORDER BY "Region", "Period"
    RegionPeriodRevenueCostresult
    Harbor112070null
    Harbor218010045.8258
    Harbor318012039.1152
    Harbor424014052.5357
    Upland1905021.2132
    Upland215011038.7298
    Upland3null9039.1152
    Upland433019080.1784

    Matches the calculation

    SELECT CAST((stddev_samp("Revenue") OVER (PARTITION BY "Region" ORDER BY "Period" ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)) AS DOUBLE) AS result FROM input ORDER BY "Region", "Period"
    RegionPeriodRevenueCostresult
    Harbor112070null
    Harbor218010042.4264
    Harbor318012034.641
    Harbor424014048.9898
    Upland19050null
    Upland215011042.4264
    Upland3null9042.4264
    Upland4330190124.9

Signature

RUNNING_STDEV(expression)