Skip to content

Data Diff Check

Definition

Asserts that two datasets match on a chosen set of fields. The check compares a target container (the dataset the check is attached to) against a reference container in another datastore, and reports every row that is added, removed, or changed between the two sides.

Recommended Check

Qualytics recommends using the Data Diff rule (dataDiff) instead of the deprecated Is Replica Of rule (isReplicaOf).

Both rules share the same row-by-row comparison engine and the same configuration properties (Row Identifiers, Passthrough Fields, and per-type Comparators). The differences:

  • Only Data Diff is actively maintained.
  • Only Data Diff supports the diff_change_types property, which restricts anomalies to a chosen subset of statuses (added, removed, changed). See How It Works for details.

Overview

Data Diff is a two-table comparison rule. Use it whenever you need to confirm that one dataset is an exact copy, or a controlled copy, of another:

  • Validating that a replica, backup, or warehouse mirror matches its source of truth.
  • Comparing pre- and post-migration data after a system move.
  • Verifying that a derived table, such as an aggregate, snapshot, or reporting view, still agrees with the upstream system.
  • Confirming that an exported file delivered to a partner contains the same rows as the system of record.

Beyond the standard properties, a Data Diff check has three configuration inputs: the reference datastore and container to compare against, an optional list of Row Identifiers (the key the platform uses to match each target row to its reference row), and an optional set of Comparators (per-field tolerances for numeric, duration, and string fields).

When Row Identifiers are set, anomalies appear in the Comparison Source Records view, which shows each differing row side by side as Left (target) vs Right (reference) values.

Field Scope

Multiple: The check evaluates one or more fields by comparing them between target and reference.

Accepted Types

Type Supported
Date
Timestamp
Integral
Fractional
String
Boolean

General Properties

Name Supported
Filter
Allows the targeting of specific data based on conditions
Coverage Customization
Allows adjusting the percentage of records that must meet the rule's conditions

The filter allows you to define a subset of data upon which the rule will operate.

It requires a valid Spark SQL expression that determines the criteria rows in the DataFrame should meet. This means the expression specifies which rows the DataFrame should include based on those criteria. Since it's applied directly to the Spark DataFrame, traditional SQL constructs like WHERE clauses are not supported.

Examples

Direct Conditions

Simply specify the condition you want to be met.

Correct usage" collapsible="true
O_TOTALPRICE > 1000
C_MKTSEGMENT = 'BUILDING'
Incorrect usage" collapsible="true
WHERE O_TOTALPRICE > 1000
WHERE C_MKTSEGMENT = 'BUILDING'

Combining Conditions

Combine multiple conditions using logical operators like AND and OR.

Correct usage" collapsible="true
O_ORDERPRIORITY = '1-URGENT' AND O_ORDERSTATUS = 'O'
(L_SHIPDATE = '1998-09-02' OR L_RECEIPTDATE = '1998-09-01') AND L_RETURNFLAG = 'R'
Incorrect usage" collapsible="true
WHERE O_ORDERPRIORITY = '1-URGENT' AND O_ORDERSTATUS = 'O'
O_TOTALPRICE > 1000, O_ORDERSTATUS = 'O'

Utilizing Functions

Leverage Spark SQL functions to refine and enhance your conditions.

Correct usage" collapsible="true
RIGHT(
    O_ORDERPRIORITY,
    LENGTH(O_ORDERPRIORITY) - INSTR('-', O_ORDERPRIORITY)
) = 'URGENT'
LEVENSHTEIN(C_NAME, 'Supplier#000000001') < 7
Incorrect usage" collapsible="true
RIGHT(
    O_ORDERPRIORITY,
    LENGTH(O_ORDERPRIORITY) - CHARINDEX('-', O_ORDERPRIORITY)
) = 'URGENT'
EDITDISTANCE(C_NAME, 'Supplier#000000001') < 7

Using scan-time variables

To refer to the current dataframe being analyzed, use the reserved dynamic variable {{ _qualytics_self }}.

Correct usage" collapsible="true
O_ORDERSTATUS IN (
    SELECT DISTINCT O_ORDERSTATUS
    FROM {{ _qualytics_self }}
    WHERE O_TOTALPRICE > 1000
)
Incorrect usage" collapsible="true
O_ORDERSTATUS IN (
    SELECT DISTINCT O_ORDERSTATUS
    FROM ORDERS
    WHERE O_TOTALPRICE > 1000
)

While subqueries can be useful, their application within filters in our context has limitations. For example, directly referencing other containers or the broader target container in such subqueries is not supported. Attempting to do so will result in an error.

Important Note on {{ _qualytics_self }}

The {{ _qualytics_self }} keyword refers to the dataframe that's currently under examination. In the context of a full scan, this variable represents the entire target container. However, during incremental scans, it only reflects a subset of the target container, capturing just the incremental data. It's crucial to recognize that in such scenarios, using {{ _qualytics_self }} may not encompass all entries from the target container.

Anomaly Types

Type Supported
Record
Flag inconsistencies at the row level
Shape
Flag inconsistencies in the overall patterns and distributions of a field

Next Steps

  • How It Works


    Full semantics: evaluation flow, Row Identifiers, Comparators, the three diff statuses (added, removed, changed), filter behavior, and how Data Diff relates to other rule types.

    How It Works

  • Examples


    Three production scenarios with sample data, anomaly messages, and the SQL equivalent of what the check evaluates.

    Examples

  • API


    Payload shape and field notes for creating a Data Diff check programmatically.

    API

  • FAQ


    Short answers to questions about Row Identifiers, Comparators, missing values, and anomaly reporting.

    FAQ