add batch remove batch split batch comment selection show hidden batches hide batch highlight batch
db<>fiddle
donate feedback about
By using db<>fiddle, you agree to license everything you submit by Creative Commons CC0.
Help with an interesting Postgres question: Why isn't an Index Only Scan used on a partition accessed via the parent table?.
WITH product_table AS (
SELECT 'Prod A' AS product, '2019-01-01'::date AS order_date, 100 AS units_sold UNION ALL
SELECT 'Prod A', '2019-01-02'::date, 200 UNION ALL
SELECT 'Prod A', '2019-01-03'::date, 300 UNION ALL
SELECT 'Prod A', '2019-01-04'::date, 100 UNION ALL
SELECT 'Prod A', '2019-01-05'::date, 200 UNION ALL
SELECT 'Prod A', '2019-01-06'::date, 300 UNION ALL
SELECT 'Prod A', '2019-01-07'::date, 200 UNION ALL
SELECT 'Prod A', '2019-01-08'::date, 200
),
cte1 AS (
SELECT *, LAG(units_sold, 1, 0) OVER (PARTITION BY product ORDER BY order_date) AS prev_units_sold,
units_sold - LAG(units_sold, 1, 0) OVER (PARTITION BY product ORDER BY order_date) diff
FROM product_table
),
cte2 AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY product ORDER BY order_date) rn1,
ROW_NUMBER() OVER (PARTITION BY product, diff ORDER BY order_date) rn2
FROM cte1
)

SELECT product, order_date, units_sold, prev_units_sold, diff,
CASE WHEN diff > 0
THEN ROW_NUMBER() OVER (PARTITION BY product, rn1 - rn2 ORDER BY order_date)
ELSE 0 END AS streak,
CASE WHEN diff > 0
THEN AVG(units_sold) OVER (PARTITION BY product, rn1 - rn2 ORDER BY order_date)
ELSE 0 END AS running_avg
FROM cte2
ORDER BY product, order_date;
product order_date units_sold prev_units_sold diff streak running_avg
Prod A 2019-01-01 100 0 100 1 100.0000000000000000
Prod A 2019-01-02 200 100 100 2 150.0000000000000000
Prod A 2019-01-03 300 200 100 3 200.0000000000000000
Prod A 2019-01-04 100 300 -200 0 0
Prod A 2019-01-05 200 100 100 1 200.0000000000000000
Prod A 2019-01-06 300 200 100 2 250.0000000000000000
Prod A 2019-01-07 200 300 -100 0 0
Prod A 2019-01-08 200 200 0 0 0