Previous(expr)
Previous (compare with the previous input row) in Power BI
Previous returns an expression's value from the previous input record. Power BI has no LAG in Power Query, so use the index-shift self-merge pattern, a SQL LAG upstream, or a DAX calculated column that finds the previous value.
Short answer: In SQL, use LAG(). In Power Query, add two index columns (0-based and 1-based) and merge the table with itself. In DAX, use CALCULATE(MAX(...), ALLEXCEPT(...), Date < current) as a calculated column.
What it does in Qlik
Previous(expr) evaluates expr on the previous input record that was not discarded by a WHERE clause. It reads from the source, so it can use fields that are not loaded. It returns NULL on the first record. With ORDER BY on a resident load it is used for "days since last order", change flags and similar.
Qlik example
Orders2:
LOAD Customer, OrderDate,
If(Customer = Previous(Customer), OrderDate - Previous(OrderDate)) AS DaysSinceLast
RESIDENT Orders
ORDER BY Customer, OrderDate;Power BI equivalent
Power Query index shift
let
Sorted = Table.Buffer(Table.Sort(Orders, {{"Customer", Order.Ascending}, {"OrderDate", Order.Ascending}})),
Idx = Table.AddIndexColumn(Sorted, "Idx", 0, 1, Int64.Type),
Prev = Table.AddIndexColumn(Sorted, "PrevIdx", 1, 1, Int64.Type),
Merged = Table.NestedJoin(Idx, {"Idx"}, Prev, {"PrevIdx"}, "P", JoinKind.LeftOuter),
Exp = Table.ExpandTableColumn(Merged, "P", {"Customer", "OrderDate"}, {"PrevCustomer", "PrevDate"}),
Days = Table.AddColumn(Exp, "DaysSinceLast", each
if [PrevCustomer] = [Customer] then Duration.Days([OrderDate] - [PrevDate]) else null, Int64.Type)
in
DaysDAX calculated column
Days since last =
VAR d = Orders[OrderDate]
VAR PrevDate =
CALCULATE ( MAX ( Orders[OrderDate] ), ALLEXCEPT ( Orders, Orders[Customer] ), Orders[OrderDate] < d )
RETURN
IF ( NOT ISBLANK ( PrevDate ), INT ( d - PrevDate ) )Gotchas and behaviour differences
- Sort and buffer before adding the index. Without
Table.Buffer, later steps are not guaranteed to keep the sort order. - The DAX version finds the previous *date*, not the previous *row*. Two orders on the same day give 0 in Qlik but measure from the previous distinct date in DAX.
Official documentation
- Previous - script function (Qlik Help)
- Table.AddIndexColumn (Power Query M) (Microsoft Learn)
- Table.NestedJoin (Power Query M) (Microsoft Learn)
- Table.Buffer (Power Query M) (Microsoft Learn)
Related pages
Peek(field_name [, row_no [, table_name]])
Peek (running balances in the script)
Peek reads a field from a row already loaded into the output table. It is used for running balances and for reading values into variables. Power Query has no row-by-row state, so use grouped list logic, a SQL window function upstream, or a DAX measure.
Partial / different approach
Above(Sum(Sales))
Above, Below, Before and After
Above() reads the value from the previous row of the chart. Power BI offers three replacements: the OFFSET window function, the PREVIOUS visual calculation, and calendar-aware time intelligence. Each behaves differently when periods are missing.
Partial / different approach
RecNo(), RowNo()
RecNo and RowNo
RecNo numbers input records and RowNo numbers output rows. In Power Query, add an index column before the filter step (RecNo) or after it (RowNo). The model has no row order, so keep the index as a column.
Partial / different approach
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.