AI Infrastructure
SQL NULL in AI Datasets: Which Rows and Values Count?
A nullable comparison can yield true, false or unknown. PostgreSQL 18 WHERE keeps only true rows, so a condition and its negation need not return every input row between them. Account for the unknown rows separately, then identify which values each aggregate uses. In the six-row example below, four supplied numbers have a mean of 15; a separately zero-filled six-number copy has a mean of 10. Those results answer different questions.
Start with six records and four supplied numbers
A data preparation offer may describe its output as all records above a threshold, all remaining records, or the average reading. Each phrase needs an explicit population. This article uses PostgreSQL 18 scalar numeric comparisons and aggregates to make those populations visible.
Fictional SQ-51 contains exactly six records, A through F. Their x values, in order, are 0, 10, null, 20, null and 30. The numbers have invented reading units. Null means that this toy supplies no numeric value for C or E. These are stipulated inputs for reasoning, not an executed query, captured dataset or model evaluation.
Zero is a supplied number in A. The text string "unknown" would be a supplied string, whereas a SQL null represents a different value state. An absent field in a writer schema is another question: the related Avro guide explains how reader defaults can supply a value. Here the x column exists for every record, and the two nulls are already part of the input representation.
References: [P1]
Trace x > 10 and its negation for every record
For the supplied numeric values, x > 10 is false for A and B and true for D and F. For C and E, ordinary comparison with null yields unknown. PostgreSQL represents that Boolean unknown as null.
Logical NOT reverses true and false but leaves unknown as unknown. It therefore cannot turn C or E into a confirmed threshold failure. The table follows the two expressions independently for the same six records. It does not assign a clinical, equipment-health or training label to any row.
Scroll the table horizontally on smaller screens.
| Record | Supplied x | x > 10 | NOT (x > 10) | Source |
|---|---|---|---|---|
| A | 0 | false | true | [P1][P2] |
| B | 10 | false | true | [P1][P2] |
| C | null | unknown | unknown | [P1][P2] |
| D | 20 | true | false | [P1][P2] |
| E | null | unknown | unknown | [P1][P2] |
| F | 30 | true | false | [P1][P2] |
Original synthetic inputs and derived outcomes. No database execution or real sensor evidence is claimed.
The two selected sets account for four of the six rows
PostgreSQL 18 WHERE retains a row when its condition is true and discards it when the outcome is false or null. Applied to x > 10, it retains D and F. Applied separately to NOT (x > 10), it retains A and B. Neither selection contains C or E.
The complete accounting is two true, two false and two unknown outcomes: 2 + 2 + 2 = 6. The union of the two selected sets contains only four records. Calling the second selection "everything else" would conceal the two unknown outcomes. Calling every row absent from the first selection a negative training example would assign a meaning that this comparison did not establish.
PostgreSQL also defines Boolean tests that distinguish these requests. For this same predicate, IS FALSE identifies A and B; IS UNKNOWN identifies C and E; IS NOT TRUE identifies A, B, C and E. Thus a request for "not true" can include both known-false and unknown cases, while ordinary NOT retains the unknown state. These are expression meanings for comparing supplied outputs, not database-change instructions.
A buyer can legitimately ask for either known threshold failures or every record outside the positive set. The returned membership and its handling of C and E must match that request. A four-row not-true set still contains only two known-false outcomes.
A six-row table can produce a four-value mean
Now return to the complete original SQ-51 input, before either threshold selection. COUNT(*) is 6 because there are six input rows. COUNT(x) is 4 because only A, B, D and F supply non-null x values. Those four numbers sum to 0 + 10 + 20 + 30 = 60 reading units. AVG(x) is therefore 60 / 4 = 15 reading units.
The zero in A participates in that four-value denominator. C and E remain records in the six-row input even though they do not contribute numeric values to this mean. A report that pairs "six records" with "mean 15" can be correct, provided it identifies that the mean covers four non-null readings.
Selection changes the aggregate input again. For D and F alone, the two readings sum to 50 and average 25. For A and B alone, they sum to 10 and average 5. Neither is the mean of all four supplied readings. The supplier needs to identify whether its aggregate covers the original input or a selected subset.
PostgreSQL's aggregate definitions determine these calculations, not whether the available readings represent the intended population. Also, an empty input does not imply a measured sum of zero: the documentation distinguishes COUNT from aggregates such as SUM, which returns null when no rows are selected.
References: [P4]
A mean of 10 belongs to a different six-number input
Define a separate hypothetical copy of SQ-51 in which C and E each receive the number 0. This stipulated transformation produces 0, 10, 0, 20, 0 and 30. Its six numbers still sum to 60, but their arithmetic mean is 60 / 6 = 10 reading units.
The unchanged sum does not establish unchanged input meaning. Four supplied readings and two unavailable values have become six numeric entries, including two chosen replacements. The mean changed because the representation and contributing population changed.
This example does not recommend zero filling. It supplies no missingness mechanism, hidden values or task-specific validation. Consequently it cannot identify the true six-record measurement mean, estimate a bias direction for a real dataset, or show whether a model would improve. A numeric replacement can be a declared application choice without becoming a recovered source observation.
An average of available readings and an average of a chosen filled representation can both be calculated honestly. The reader needs to know which one is being purchased or consumed.
Compare offers using membership, values and the requested statistic
Suppose offer A supplies the two above-threshold rows D and F and reports 15 as the available-reading mean over the original input. A complete explanation accounts for all six original records: two true outcomes, two false outcomes and two unknown outcomes, with four contributing readings in the mean. The mean and the threshold result refer to different, explicitly identified populations.
Offer B supplies D and F as positives and A and B as negatives, but says those files partition all six records. That claim fails SQ-51 because C and E appear in neither file. A separate unknown population would resolve the missing membership accounting; relabeling C and E as negatives would instead change the application rule.
Offer C supplies all six rows after the stated zero fill and reports 10 as the resulting mean. Its return can satisfy a request for that transformed representation if it identifies both replacements. It cannot satisfy a request for six observed readings merely because all six entries are now numeric.
Before choosing, have the appointed data-platform or application provider connect the delivered row identities to the named condition, account for the unknown outcomes, and identify the exact values and population behind the statistic. This concrete comparison separates missing rows, unavailable values and chosen replacements without treating one of them as proof of another. The related Arrow and Parquet guides address earlier value interpretation and physical scan work; neither determines this SQL result membership.
Keep a separate equipment-cabling requirement concrete
If the surrounding AI platform also needs physical compute-to-storage connections, Leviathan's Structured Cabling & Fiber Installation service is the relevant route for that defined work. Share the selected equipment, approved endpoints and pathways, material responsibilities and required connection records through the related project inquiry.
SQL selection, missing-value treatment and application validation belong with the appointed software providers. The physical cabling discussion concerns the agreed connections and handoff.
References: [L1]
Primary sources
- [P1] PostgreSQL 18: Comparison Functions and Operators, section 9.2Checked 2026-10-21. Ordinary scalar comparisons involving null and Boolean IS TRUE, IS FALSE, IS UNKNOWN and IS NOT TRUE predicates. Composite-row and other special comparison rules are outside SQ-51.
- [P2] PostgreSQL 18: Logical Operators, section 9.1Checked 2026-10-21. Three-valued Boolean truth tables, including NOT null remaining null. This supports the two independently evaluated expressions in SQ-51.
- [P3] PostgreSQL 18: The WHERE Clause, section 7.2.2Checked 2026-10-21. Defines retaining true rows and discarding false or null outcomes. This article uses a single supplied scalar column, without join or grouping rules.
- [P4] PostgreSQL 18: Aggregate Functions, section 9.21Checked 2026-10-21. COUNT(*) row count, COUNT(expression) non-null input count, AVG non-null mean, and the empty-input SUM qualification. Derived SQ-51 totals are original arithmetic.
- [L1] Leviathan Systems: Structured Cabling & Fiber InstallationChecked 2026-10-21. Physical fiber/copper connections to agreed pathways, endpoints and labels; supports the separate equipment-connection inquiry, not a data-platform software offering.