RangeAvg(Above(Sum(Sales), 0, 3))

Moving averages with RangeAvg(Above(...)) in Power BI

RangeAvg(Above(Sum(Sales), 0, 3)) gives a 3-row moving average. In Power BI, use WINDOW with AVERAGEX, the MOVINGAVERAGE visual calculation, or a calendar-based DATESINPERIOD measure.

Partial / different approach DAX

Short answer: AVERAGEX(WINDOW(-2, REL, 0, REL, ALLSELECTED('Date'[YearMonth]), ORDERBY('Date'[YearMonth])), [Sales]) is row-based like Qlik. In a visual, MOVINGAVERAGE([Sales], 3) does the same.

What it does in Qlik

RangeAvg averages its numeric arguments and ignores NULL and text. Feeding it Above(expr, 0, 3) (current row plus the two above) gives a trailing 3-row average. On the first rows, fewer values are averaged.

Qlik example

Qlik chart expression
RangeAvg(Above(Sum(Sales), 0, 3))

Power BI equivalent

Window function

DAX
Sales 3M avg =
AVERAGEX (
    WINDOW ( -2, REL, 0, REL, ALLSELECTED ( 'Date'[YearMonth] ), ORDERBY ( 'Date'[YearMonth], ASC ) ),
    [Sales]
)

Calendar-based

DAX
Sales 3M avg (calendar) =
CALCULATE (
    AVERAGEX ( VALUES ( 'Date'[YearMonth] ), [Sales] ),
    DATESINPERIOD ( 'Date'[Date], MAX ( 'Date'[Date] ), -3, MONTH )
)

Visual calculation

DAX (visual calculation)
3M avg = MOVINGAVERAGE ( [Sales], 3 )

Gotchas and behaviour differences

  • Do not write AVERAGEX(DATESINPERIOD(...), [Sales]). That averages per day. Iterate the month column as shown.
  • AVERAGEX skips BLANK results, like RangeAvg skips nulls. A month with no sales is therefore left out of the average, not counted as 0. Use [Sales] + 0 if it should count as 0.
  • Put the column used in ORDERBY on the visual's axis. If the axis shows another column from the same table instead, such as a month name sorted by YearMonth or a text key sorted by an index column, that column's filter stays on every row and the window shrinks to the current row. Fix both parts. Use SUMMARIZE(ALLSELECTED('Date'), 'Date'[YearMonth]) as the relation, and remove the label column's filter with REMOVEFILTERS('Date'[MonthName]) in the surrounding CALCULATE. Also don't call ALLSELECTED inside an iterator such as SUMX, where it returns only the rows being iterated. Compute it in a variable before the iterator.
  • Qlik's version moves over displayed rows. The calendar version moves over calendar months, whether or not they have data.
  • Visual calculations have limits that matter when you migrate: you can't filter or sort a visual by them, change their aggregation, or reuse them in another visual. Data exports leave them out. They don't support dynamic format strings or Show items with no data. Slicers, custom visuals and paginated reports don't support them, and you can't pin a visual that uses them to a dashboard or publish it to the web. If any of these matter, use the model measure instead. (Microsoft's list)

Official documentation

Related pages

Spotted an error or a better pattern? QlikToDax is maintained by a working BI consultant; corrections are welcome via the About page. Last reviewed 2026-10-25.