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.

Partial / different approach Power Query DAX SQL

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

Qlik script
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

Power Query M
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
    Days

DAX calculated column

DAX
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

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.