WHERE Modified >= '$(vLast)' ... Concatenate ... WHERE NOT Exists(ID); STORE ... INTO x.qvd
QVD incremental load in Power BI
The QVD incremental pattern (load the changes, append the old QVD rows not in the change set, store) has no file-level equivalent in Power BI. Use the incremental refresh policy on the semantic model, or in Fabric land the data in a Delta table with MERGE.
What it does in Qlik
The classic Qlik pattern: - read rows changed since the last run from the database - concatenate the historic QVD rows whose key is not in the new set (WHERE NOT Exists(ID)) - optionally inner join to the current key list to remove deleted rows - STORE the result back to the QVD
The QVD is a persistent, app-independent cache.
Qlik example
LET vLast = Peek('MaxModified', 0, 'LastRun'); // from a previous step
Orders:
SQL SELECT * FROM dbo.Orders WHERE ModifiedDate >= '$(vLast)';
Concatenate (Orders)
LOAD * FROM [lib://Data/Orders.qvd] (qvd) WHERE NOT Exists(OrderID);
Inner Join (Orders) SQL SELECT OrderID FROM dbo.Orders; // handle deletes
STORE Orders INTO [lib://Data/Orders.qvd] (qvd);Power BI equivalent
Incremental refresh filter (Power Query)
// RangeStart and RangeEnd: parameters of type Date/Time (names are mandatory)
= Table.SelectRows(Orders, each [OrderDate] >= RangeStart and [OrderDate] < RangeEnd)Then, in Desktop: right-click the table, choose Incremental refresh, and set the archive and refresh windows. Optionally turn on Detect data changes on a ModifiedDate column. Publish, and the service creates and manages the partitions.
Fabric lakehouse upsert (Spark SQL)
MERGE INTO lakehouse.orders AS t
USING staging_orders AS s
ON t.OrderID = s.OrderID
WHEN MATCHED THEN UPDATE SET *
WHEN NOT MATCHED THEN INSERT *;Gotchas and behaviour differences
- Use
>=on one boundary and<on the other. Otherwise rows on partition edges are loaded twice or not at all. - Partition on a date that does not change (such as OrderDate). Partitioning on ModifiedDate moves rows between partitions and creates duplicates. Use ModifiedDate for Detect data changes instead.
- The filter must fold to the source (check View native query). Otherwise every partition refresh reads the whole table.
- Incremental refresh does not remove rows deleted in the source from partitions it doesn't refresh. Run a periodic full or partition refresh, or handle deletes upstream.
- Licensing: incremental refresh works on Pro, Premium Per User, Premium/Fabric capacity and Embedded. Real-time data (a DirectQuery partition for the newest rows) needs Premium, PPU or Embedded, not Pro. XMLA-endpoint partition management, such as refreshing single partitions from SSMS or Tabular Editor, also needs Premium/PPU/Fabric capacity. Each refresh still has the usual time limit: 2 hours on Pro, 5 hours on Premium/Fabric capacity.
Official documentation
- Using QVD files for incremental load (Qlik Help)
- Incremental refresh for semantic models (Microsoft Learn)
- Configure incremental refresh (Microsoft Learn)
- Lakehouse and Delta tables (Fabric) (Microsoft Learn)
Related pages
WHERE Exists(field [, expr])
Where Exists / Not Exists
Exists() checks whether a value has already been loaded into a field anywhere in the script. In Power Query, filter against a buffered list from another query, or use an inner or anti merge. Qlik's "everything loaded so far" behaviour is order-dependent, and Power Query has nothing like it.
Partial / different approach
Concatenate [(table)] LOAD ...
Concatenate (append tables)
Concatenate appends rows to an existing table. Qlik also does this automatically when field sets match. Power Query's Append queries (Table.Combine) matches columns by name and fills missing ones with null.
Direct equivalent
LOAD ... RESIDENT table; DROP TABLE table;
Resident load and intermediate tables
A Resident load reads a table already in memory. The Power Query equivalent is a referenced query, but it re-runs its source instead of reading from memory. Heavy multi-step transformations are better done upstream in a warehouse, dataflow or lakehouse.
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.