Equal To Field Check Examples
Three real-world scenarios that show how the Equal To Field check is typically used in production: keeping a denormalized copy in step with its source, reconciling two systems on a tolerated amount, and auditing a migrated column mid-cleanup. The first two run at 100% coverage and report Record Anomalies; the third lowers coverage and reports a Shape Anomaly instead.
The situation: Order rows carry a denormalized customer_city copied from the customer record at order time. A nightly job refreshes it. When the copy drifts from billing_city, downstream reports segment customers into the wrong region.
Check configuration
| Field | Value |
|---|---|
| Rule | Equal To Field |
| Field | customer_city |
| Filter | (none) |
| Custom Anomaly Description | Off |
| Field to compare | billing_city |
| String | (none) |
| Datetime | (none) |
| Numeric | (none) |
| Coverage | 100% |
| Owner | (check creator) |
| Anomaly Assignee | (Customer Data team) |
| Description | The denormalized customer city must match the billing city. |
| Tags | consistency, denormalization |
| Additional Metadata | jira: DATA-10210 |
| Status | Active |
Payload
{
"description": "The denormalized customer city must match the billing city.",
"rule": "equalToField",
"fields": ["customer_city"],
"container_id": 145,
"coverage": 1,
"filter": null,
"properties": {"field_name": "billing_city"},
"tags": ["consistency", "denormalization"],
"additional_metadata": {"jira": "DATA-10210"},
"anomaly_message_field": null,
"template_id": null,
"status": "Active",
"owner_id": 7,
"default_anomaly_assignee_id": 12
}
Sample Data
| order_id | customer_city | billing_city |
|---|---|---|
| O-001 | Lisbon | Lisbon |
| O-002 | Porto | Braga |
| O-003 | (null) | Faro |
What gets flagged
Order O-002 kept a stale copy after the customer moved. O-003 has no copy yet, and NULLs pass, so it is not reported. Coverage is 100%, so the failing row is reported as a Record Anomaly.
Record Anomaly
The field 'customer_city' has value Porto, which is not equal to the value of 'billing_city'
Flowchart
graph TD
A["No filter, evaluate all rows"] --> B["Read customer_city"]
B --> C{"Is value NULL?"}
C -->|Yes| D["Row passes"]
C -->|No| E{"Does customer_city equal billing_city?"}
E -->|Yes| D
E -->|No| F["Flag row.<br/>Record Anomaly per failing row."]
Equivalent SQL
The situation: The billing system and the ledger both write the invoice total onto the same row. They round at different points, so amounts can differ by a cent without anything being wrong. A two-cent absolute tolerance absorbs that: the margin is exclusive, so a difference has to be strictly smaller than the epsilon to pass, and a one-cent gap needs a margin above one cent. Voided invoices are excluded with a filter, because the ledger never writes them.
Check configuration
| Field | Value |
|---|---|
| Rule | Equal To Field |
| Field | ledger_total |
| Filter | status <> 'voided' |
| Custom Anomaly Description | Off |
| Field to compare | billing_total |
| String | (none) |
| Datetime | (none) |
| Numeric | Absolute, 0.02 |
| Coverage | 100% |
| Owner | (check creator) |
| Anomaly Assignee | (Finance Data team) |
| Description | The ledger total must match the billing total, within two cents. |
| Tags | finance, reconciliation |
| Additional Metadata | jira: DATA-10233 |
| Status | Active |
Payload
{
"description": "The ledger total must match the billing total, within two cents.",
"rule": "equalToField",
"fields": ["ledger_total"],
"container_id": 512,
"coverage": 1,
"filter": "status <> 'voided'",
"properties": {"field_name": "billing_total", "numeric_comparator": {"epsilon": 0.02, "as_absolute": true}},
"tags": ["finance", "reconciliation"],
"additional_metadata": {"jira": "DATA-10233"},
"anomaly_message_field": null,
"template_id": null,
"status": "Active",
"owner_id": 7,
"default_anomaly_assignee_id": 47
}
Sample Data (filtered to status <> 'voided')
| invoice_id | status | ledger_total | billing_total |
|---|---|---|---|
| I-01 | issued | 1240.00 | 1240.01 |
| I-02 | issued | 980.00 | 1080.00 |
| I-03 | issued | 305.50 | 305.50 |
Why the filter matters
The filter runs before the comparison, so voided invoices, which the ledger never receives, are never evaluated and cannot inflate the violation count.
What gets flagged
I-01 differs by one cent, inside the tolerance, so it passes. I-02 is out by a hundred, far beyond the margin, and fails. Coverage is 100%, so the failure is reported as a Record Anomaly, and the message ends with the filter that scoped the evaluation.
Record Anomaly
The field 'ledger_total' has value 980.00, which is not equal to the value of 'billing_total' [filter: status <> 'voided']
Flowchart
graph TD
A["Apply filter: status <> 'voided'"] --> B["Read ledger_total and billing_total"]
B --> C["Apply the 0.02 tolerance"]
C --> D{"Do the two values agree?"}
D -->|Yes| E["Row passes"]
D -->|No| F["Flag row.<br/>Anomaly message ends with<br/>[filter: status <> 'voided']"]
Equivalent SQL
-- Rows the check would flag, allowing anything strictly under two cents.
SELECT i.*
FROM invoices i
WHERE i.status <> 'voided'
AND NOT (
(i.ledger_total IS NULL AND i.billing_total IS NULL)
OR (i.ledger_total IS NOT NULL AND i.billing_total IS NOT NULL
AND abs(i.ledger_total - i.billing_total) < 0.02)
);
The situation: A migration recalculated region_code and wrote it beside the legacy legacy_region. The two should agree everywhere, but the legacy loader padded some values and a backfill for older records is still running, so a small share is expected to lag. Coverage is lowered to 98% while the backfill finishes.
Check configuration
| Field | Value |
|---|---|
| Rule | Equal To Field |
| Field | region_code |
| Filter | (none) |
| Custom Anomaly Description | Off |
| Field to compare | legacy_region |
| String | Ignore Whitespace |
| Datetime | (none) |
| Numeric | (none) |
| Coverage | 98% |
| Owner | (check creator) |
| Anomaly Assignee | (Migration team) |
| Description | The recalculated region must match the legacy region. |
| Tags | migration, consistency |
| Additional Metadata | jira: DATA-10251 |
| Status | Active |
Payload
{
"description": "The recalculated region must match the legacy region.",
"rule": "equalToField",
"fields": ["region_code"],
"container_id": 733,
"coverage": 0.98,
"filter": null,
"properties": {"field_name": "legacy_region", "string_comparator": {"ignore_whitespace": true}},
"tags": ["migration", "consistency"],
"additional_metadata": {"jira": "DATA-10251"},
"anomaly_message_field": null,
"template_id": null,
"status": "Active",
"owner_id": 7,
"default_anomaly_assignee_id": 41
}
Sample Data
| record_id | region_code | legacy_region |
|---|---|---|
| R-01 | EMEA | EMEA |
| R-02 | APAC | EMEA |
| R-03 | LATAM | NAMER |
| R-04 | (null) | (null) |
What gets flagged
R-01 differs only in padding, which the String comparator's Ignore Whitespace option removes, so it passes. R-02 and R-03 were recalculated into a different region and fail. R-04 is empty on both sides, which passes, but still counts in the scanned total. Only 50% of the rows pass, below the 98% coverage threshold, so the check reports a single Shape Anomaly for the dataset with a sample of the offending rows. Coverage below 100% does not produce Record Anomalies.
Configuring a comparator also changes how empty values are treated. Had R-04 carried a value on one side only, it would have been reported as well, because with a comparator set a row passes only when both sides are present and match, or when both sides are NULL.
Shape Anomaly
For the field 'region_code', 50.000% of 4 records (2) are not equal to the value of 'legacy_region'
Flowchart
graph TD
A["No filter, evaluate all rows"] --> B["Read region_code and legacy_region"]
B --> C{"Are both values NULL?"}
C -->|Yes| D["Row passes"]
C -->|No| E{"Do they match once<br/>whitespace is collapsed?"}
E -->|Yes| D
E -->|No| F["Flag row.<br/>Passing rate falls below the 98%<br/>coverage, so one Shape Anomaly is reported."]
Equivalent SQL
-- Rows the check would flag, ignoring whitespace differences.
SELECT r.*
FROM records r
WHERE NOT (
(r.region_code IS NULL AND r.legacy_region IS NULL)
OR (r.region_code IS NOT NULL AND r.legacy_region IS NOT NULL
AND regexp_replace(trim(r.region_code), '\\s+', ' ')
= regexp_replace(trim(r.legacy_region), '\\s+', ' '))
);
See Also
-
Best Practices
Guidelines for choosing the reference field, setting tolerances, and deciding between this rule and its alternatives.
-
Permissions
The team permission each action needs: view, create, edit, archive, restore, and delete.
-
How It Works
The complete reference: definition, field scope, the compared field, the three comparators, NULL handling, filter behavior, and coverage.
-
Anomaly Reporting
The anomaly messages the check produces, what the numbers mean, Source Records highlighting, and Custom Anomaly Description.