Your decision table leaves outcomes unresolved despite complete-looking rows

The finished table

This week, you are looking at a table that seems ready to release: four rows cover credit score and debt-to-income, and every row has an outcome in this demo case, a referral table for a small consumer loan built for this article. A sweep of the demo table tells a different story. Across credit scores from 500 to 850 in steps of 10 and debt-to-income values from 0% to 60% in steps of 5, the table covered 468 combinations, yet 144 produced no outcome. That is 31% of the sweep. The first gap appeared at a score of 620 and debt-to-income of 35%. A complete-looking grid can still leave a large part of the decision space unresolved.

RowCredit scoreDebt-to-incomeOutcome
1700 or moreunder 35%approve
2620 to 699under 35%refer
3under 620under 100%decline
4650 to 72020% to 30%approve

The rows also leave three choices open: which matching row has the final say, where a row accepting any value sits, and what the table reads when a number is missing.

Matching rows

A table can evaluate every row from top to bottom, so every matching row writes its result and the lowest matching row has the final say. This is how a new table is set up. The other choice stops evaluation at the first matching row. The distinction matters for a policy written as an ordered list: below 500, decline; otherwise below 650, refer; otherwise approve. Under last-match, an applicant whose application matches more than one row receives the later label instead of the first. The choice is stored with the table and travels into every release.

One application makes the distinction plain. One row approves amounts above zero, and a later row refers amounts above 10,000. An applicant asking for 5,000 is approved under either setting because only the first row matches. An applicant asking for 25,000 matches both rows: the applicant is referred when the last matching row wins and approved when the first matching row wins.

Decisimo decision engine

Put these checks into a decision flow

Create rules for credit, fraud or collections, then run them on live decisions.

Catch-all placement

That same table can contain a catch-all row: when every condition accepts any value, the row matches every application. Its position only makes sense alongside the rule for matching rows. An applicant with a score of 720 matched both “any score: refer” and “score 700 or more: approve”. The catch-all came first and the last matching row won, so the result was approve; with the first matching row winning, the result was refer.

When the catch-all moved to the end, the applicant with a score of 720 was referred under the last-match choice and approved under the first-match choice. In the wrong position, the catch-all overrides the more specific row, so placement is a deliberate policy choice rather than a universal convention. The overlap check treats that choice separately: it reported zero overlapping pairs and recorded the catch-all’s position as “first” or “last”, rather than reporting it as an ordinary overlap with every other row.

Missing inputs

A missing number can still satisfy a numeric condition. In the row that approves debt-to-income between 0 and 35, an applicant who supplied 25 was approved, and so was an applicant who supplied no debt-to-income value at all. The table reads the missing field as zero for that comparison. The applicant who disclosed 25% and the applicant who left the field blank both received approval, and an analyst cannot tell them apart from the outcome alone.

If a missing figure should lead to referral or decline, make that case explicit above the other rows. An is null or is not a number condition gives absence its own result before the numeric comparison can approve it. Decide what the table should do when the number you expected is not there.

A visible set of rows and a test window give useful checks, but neither settles every unresolved outcome. The overlap check compares pairs of rows that some application could satisfy together; on the demo table it found two such pairs, rows 1 and 4 and rows 2 and 4, with none left unchecked. The decision-table overlap check does not look for gaps. Simulation runs a sample built from the values or numeric ranges you provide, then counts each result; applications with no result appear under an empty value.

That is evidence from the sample, not proof of the whole decision space. The grid sweep from the opening still found combinations with no outcome.

Release check

The release check should use three deliberate applications rather than another glance at the grid. Give the table a score of 680 and debt-to-income of 25%, where rows 2 and 4 can both match: expect approve when the last matching row wins and refer when the first matching row wins. Then use a score of 720 against a catch-all row and a row for scores of 700 or more; move the catch-all from first to last and check the result under each matching rule.

Finally, test an applicant who leaves debt-to-income blank. The row covering debt-to-income from 0 through 35 reads that absence as zero, so its result is approve.

Before the table goes live, run those applications as unit tests or as one complete-object test, with the expected result written down for each.

Decisimo decision engine

Put these checks into a decision flow

Create rules for credit, fraud or collections, then run them on live decisions.