Hash128(CustomerID, OrderDate) AS RowHash

Hash128 and Hash256 in Power BI

No 1:1 equivalent in Power Query or DAX. Neither has a hash function. Qlik developers use Hash128 and Hash256 for change detection in incremental loads, for anonymising IDs, or for stable composite keys. Do this upstream: HASHBYTES in SQL Server, Azure SQL or Fabric Warehouse, or sha2() in a Fabric notebook or Spark.

No 1:1 equivalent Fabric SQL

Short answer: Compute the hash in the source query or the warehouse, then load it as a column. For a composite key you only use inside the model, a concatenated text key works just as well.

What it does in Qlik

Hash128(expr, ...), Hash160 and Hash256 return a hash string of the combined input values. Unlike AutoNumber, the result is the same across reloads and apps.

Qlik example

Qlik script
LOAD *, Hash128(CustomerID, Name, Address, City) AS RowHash
FROM [lib://Data/customers.qvd] (qvd);

Power BI equivalent

SQL (source query or Fabric Warehouse)

SQL
SELECT c.*,
       HASHBYTES('SHA2_256', CONCAT_WS('|', CustomerID, Name, Address, City)) AS RowHash
FROM dbo.Customers AS c;

Fabric notebook (PySpark)

Python
from pyspark.sql.functions import sha2, concat_ws
df = df.withColumn("RowHash", sha2(concat_ws("|", "CustomerID", "Name", "Address", "City"), 256))

Gotchas and behaviour differences

  • Use a separator such as '|', or the values ("ab", "c") and ("a", "bc") hash the same. Treat NULLs explicitly, because CONCAT_WS skips them.
  • Hashes from different engines won't match Qlik's Hash128, because the algorithm and encoding differ. Recompute all of them during the migration rather than comparing old and new.

Official documentation

Related pages

AutoNumber(CustomerID & '|' & Region) AS %CustKey AutoNumber and surrogate keys Qlik developers use AutoNumber() to replace long text or composite keys with compact integers, which saves RAM and speeds up associations. In Power BI you rarely need it. VertiPaq dictionary-encodes every column, and relationships work on text keys. When you need a single-column key because a relationship can't use two columns, build a dimension with Table.AddIndexColumn and merge it into the fact. Partial / different approach WHERE Modified >= '$(vLast)' ... Concatenate ... WHERE NOT Exists(ID); STORE ... INTO x.qvd QVD incremental load 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. Partial / different approach STORE Orders INTO [lib://Data/Orders.qvd] (qvd); STORE INTO (writing QVDs) Power Query in Power BI Desktop can't write files. A query only feeds the model. Qlik's STORE pattern, transforming once, saving a QVD and reusing it, maps to Fabric: a Dataflow Gen2 with a data destination such as a Lakehouse table, a notebook writing Delta tables, or a Power BI dataflow that other models connect to. A Power BI dataflow (Gen1) only needs Pro licences, but it stores its output internally, not as files you manage. Without Fabric, the most robust answer is to store in your database or SQL views. 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.