Unlock a world of possibilities! Login now and discover the exclusive benefits awaiting you.
With the new MERGE prefix, your incremental QVD script can have a much cleaner and faster code.
Since the introduction of the new MERGE prefix (https://help.qlik.com/en-US/sense/May2022/Subsystems/Hub/Content/Sense_Hub/Scripting/ScriptPrefixes/...) has become much easier to create an incremental load using a Qlik script. This command receives a table with insert, update, and delete operations and can change a table already loaded in memory.
For the examples below we have two assumptions:
Let's see the examples:
1 -"Insert Only Case
QVDFile='lib://DataFiles/NW.Orders_InsertOnly.qvd';if FileSize('$(QVDFile)') > 0 then //If there is already extracted data[NW.Orders]:Load OrderID,CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountryfrom [$(QVDFile)](qvd);t:load Max(OrderID) as MaxOrderID Resident [NW.Orders];LastOrderID=Peek('MaxOrderID'); // Retrieves the last OrderIDDrop Table t;else LastOrderID = '0';[NW.Orders]:load null() as OrderID AutoGenerate 0; // fake tableendifMerge(updated_dt) on OrderID Concatenate([NW.Orders])Load If(Exists(OrderID),'U','I') as Operation, *; // New record? based on OrderIDSELECT OrderID,CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry,updated_dtFROM northwind.ordersWhere OrderID > '$(LastOrderID)';Store [NW.Orders] into [$(QVDFile)](qvd);
2 - "Insert" & "Update" CaseQVDFile='lib://DataFiles/NW.Orders_InsertUpdate.qvd';if FileSize('$(QVDFile)') > 0 then //If there is already extracted data[NW.Orders]:Load OrderID,CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry,updated_dtfrom [$(QVDFile)](qvd);t:load Max(updated_dt) as updated_dt Resident [NW.Orders];updated_dt=Timestamp(Peek('updated_dt'),'YYYY-MM-DD hh:mm:ss.fff'); // Retrieves the last udpateDrop Table t;else updated_dt = '2000-01-01';[NW.Orders]:load null() as OrderID AutoGenerate 0; // fake tableendifMerge(updated_dt) on OrderID Concatenate([NW.Orders])Load If(Exists(OrderID),'U','I') as Operation, *; // New record? based on OrderIDSELECT OrderID,CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry,updated_dtFROM northwind.ordersWhere updated_dt > '$(updated_dt)';Store [NW.Orders] into [$(QVDFile)](qvd);
3 – Insert / Update / Delete Case QVDFile='lib://DataFiles/NW.Orders_InsertUpdateDelete.qvd';if FileSize('$(QVDFile)') > 0 then //If there is already extracted data[NW.Orders]:Load OrderID,CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry,updated_dtfrom [$(QVDFile)](qvd);t:load Max(updated_dt) as updated_dt Resident [NW.Orders];updated_dt=Timestamp(Peek('updated_dt'),'YYYY-MM-DD hh:mm:ss.fff'); // Retrieves the last udpateDrop Table t;else updated_dt = '2000-01-01';[NW.Orders]:load null() as OrderID AutoGenerate 0; // fake tableendifMerge(updated_dt) on OrderID Concatenate([NW.Orders])Load If(Exists(OrderID),'U','I') as Operation, *; // New record? based on OrderIDSQL SELECT OrderID,CustomerID,EmployeeID,OrderDate,RequiredDate,ShippedDate,ShipVia,Freight,ShipName,ShipAddress,ShipCity,ShipRegion,ShipPostalCode,ShipCountry,updated_dtFROM northwind.ordersWhere updated_dt > '$(updated_dt)';//Keeping only records which OrderID is still in databaseInner Keep([NW.Orders])SQL SELECT DISTINCT OrderIDFROM northwind.orders;Store [NW.Orders] into [$(QVDFile)](qvd);
I highly recomend to use fieldvalue() + autogenerate(fieldvaluecount()) instead of resident load like;
Max(FieldValue('OrderID',recNo())) as MaxOrderID AutoGenerate(FieldValueCount('OrderID'));
Hi,
thanks for this, best example I’ve found so far on the merge logic.
@blaise Do you have a complete example with fieldvalue ? Haven’t been able to get this to work.
Dear @Clever_Anjos ,
//i am trying the Merge prefix solution from above but it is slower then traditional incremental load.
i'm sorry my analysis was not good. i'm seeing a big performance update true merge. Thanks for the explanation!
@qlikster
Load min(OrderDate) as MinDate, max(OrderDate) as MaxDate; Load FieldValue('%OrderDate',IterNo()) as OrderDate autogenerate(1) while not IsNull(FieldValue('%OrderDate',Iterno()));
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.