Docs · Troubleshooting
When nothing matches
Every row shows as missing on both sides. Six causes, in the order worth checking.
The commonest first-run result is the alarming one: both systems returned rows, the totals look plausible, and almost every row comes back Missing, on both sides at once.
That symptom — the same business entity appearing twice, unmatched, once per source — is nearly always a key that does not line up. The figures are fine. The join is not.
Work through these in order. The first three account for most of it.
#1. The two codes are spelled differently
S014 against 014. 1710104 against W-MADRID SERRANO. A padded code against an unpadded one.
Check: open both sources' Result tabs and read the key column on each. Put them side by side.
Fix: normalise the side that is wrong, or both to a common shape. Drop leading zeroes and Digits only handle most of it. If only one system is odd, fix it on that data source so every Check built on it inherits the fix. See Normalise.
#2. Case differs
s014 and S014 are two different keys. Matching is case-sensitive and deliberately so — silently merging codes that differ only by case would hide a real data problem.
Fix: add UPPERCASE to that key's rule. Because key rules apply to every input, setting it once fixes both sides.
#3. One side is a timestamp and the other is a date
2026-09-07 against 2026-09-07T00:30:00. These never match, and it is invisible in a table that formats both as a date.
Fix: Date only, drop the time on the timestamped side.
If the two systems are in different time zones, apply Shift by hours first and Date only second. In that order — truncating first throws away the information the shift needs.
#4. Rows are being dropped for having no key
Look at the summary for Excluded (no key), and at the run warning: "Input "POS": 412 row(s) had a null or empty key and were excluded from the join."
A blank key usually means the column you mapped is not the one you meant, or the query returns a footer row, or an outer join upstream is producing nulls.
Fix: correct the mapping, or exclude those rows deliberately with a row filter so the count stops being a surprise.
#5. The grain does not match
One source returns one row per receipt line, the other one row per store per day. The keys are right; there is simply more than one row on one side for each row on the other.
Symptom: the counts are wildly different between sides, and measures on the fine-grained side look far too large.
Fix: group in the query, or let the aggregation do it — the measure's aggregate function is there for exactly this. Make both sides return the grain you are comparing at.
#6. You are comparing different populations
Not a formatting problem at all. One side includes online orders, or returns, or a shop that closed in March.
Symptom: matched rows agree perfectly, and the unmatched ones are all of one kind — all web, all one region, all after a date.
Fix: narrow one side with a parameter or a row filter. This is the good outcome: the Check just told you something true about your estate.
#A useful habit
Before trusting a Check, run it deliberately narrowed — one store, one day. A handful of rows you can read by eye will tell you in thirty seconds what a hundred thousand rows will hide for an afternoon.