Advanced SQL & Data Engineering • Training 10
Article-Training • SQL Server–Friendly Series

NULL Semantics

The SQL Logic That Tricks Everyone

NULL is about missing or unknown information — and SQL treats that differently.

NULL → UNKNOWN → Filter Behavior → Join Behavior → Aggregate Behavior → Safe Patterns
TRUE
|
FALSE
|
UNKNOWN
= NULL ❌
→
IS NULL ✅
8learning modules
24interactive practices
5rapid review questions
50%certificate threshold
Learning target
Reason correctly about NULL so SQL results match the business meaning.
Practice progress0 / 24

Complete 12 of 24 practices (50%) and enter your name to unlock the Certificate of Participation.

MODULE 01
🧠

Three-Valued Logic: TRUE, FALSE and UNKNOWN

SQL does not use ordinary two-valued Boolean logic when NULL is involved. A comparison with an unknown value usually produces UNKNOWN, and WHERE keeps only TRUE.

❓
UNKNOWN is the missing piece

If Salary is NULL, the predicate Salary > 50000 is not FALSE. SQL cannot know whether it is true or false, so the result is UNKNOWN.

Core ideas

  • NULL means unknown/missing, not a regular value
  • Comparisons with NULL usually return UNKNOWN
  • WHERE preserves only TRUE
  • UNKNOWN explains many 'missing row' surprises
Three-valued logic
-- Salary = NULL
Salary > 50000   --> UNKNOWN
Salary = 50000   --> UNKNOWN
Salary <> 50000  --> UNKNOWN

-- WHERE only keeps TRUE rows.
✅

Once UNKNOWN becomes part of your mental model, NULL behavior stops looking random.

Practice — 3 cases

Practice 1 / Práctica 1
What does NULL represent in SQL?
Practice 2 / Práctica 2
What is the result of 5 = NULL in normal SQL comparison semantics?
Practice 3 / Práctica 3
Why does WHERE reject UNKNOWN?
MODULE 02
🎯

IS NULL and IS NOT NULL: Use the Right Operators

NULL is not compared with = or <>. SQL provides dedicated predicates: IS NULL and IS NOT NULL.

❓
NULL is a state, not a normal comparable value

A filter like ClosedDate = NULL returns no TRUE matches under normal semantics. ClosedDate IS NULL expresses the actual question.

Core ideas

  • Use IS NULL for missing values
  • Use IS NOT NULL for present values
  • Avoid = NULL and <> NULL
  • Make nullability intent obvious in code reviews
Correct NULL tests
-- Correct
WHERE ClosedDate IS NULL

-- Correct
WHERE ClosedDate IS NOT NULL

-- Incorrect logic
WHERE ClosedDate = NULL
WHERE ClosedDate <> NULL
✅

NULL tests should be explicit so both SQL Server and the next developer know exactly what you mean.

Practice — 3 cases

Practice 4 / Práctica 4
Which predicate correctly tests whether a column is NULL?
Practice 5 / Práctica 5
Which predicate correctly tests for non-NULL values?
Practice 6 / Práctica 6
Why is = NULL unsafe?
MODULE 03
⚠️

The NOT IN + NULL Trap

One of SQL's most famous NULL surprises appears in NOT IN. If the subquery includes NULL, the predicate can become UNKNOWN for rows you expected to keep.

❓
One NULL can change the whole anti-filter

If you ask for CustomerID NOT IN (1,2,NULL), SQL cannot prove that CustomerID is different from the unknown value, so the result may not be TRUE.

Core ideas

  • NOT IN is sensitive to NULLs in its list/subquery
  • NOT EXISTS expresses anti-matching more safely
  • If using NOT IN, exclude NULLs explicitly
  • Test anti-joins with NULL-containing data
Safer anti-join
-- Risky if BlockedCustomerID contains NULL
WHERE CustomerID NOT IN
(
    SELECT BlockedCustomerID
    FROM dbo.BlockedCustomer
)

-- Safer
WHERE NOT EXISTS
(
    SELECT 1
    FROM dbo.BlockedCustomer AS b
    WHERE b.BlockedCustomerID = c.CustomerID
);
✅

If NULLs are possible, NOT EXISTS is usually the clearer and safer anti-join pattern.

Practice — 3 cases

Practice 7 / Práctica 7
Why can NOT IN return no rows when the subquery contains NULL?
Practice 8 / Práctica 8
Which anti-join is generally safer when NULLs may exist?
Practice 9 / Práctica 9
How can NOT IN be made safer if you truly want to use it?
MODULE 04
🔗

NULL and Outer Joins: ON vs WHERE Matters

Outer joins intentionally create NULLs for missing matches. A filter placed in WHERE can then remove those NULL-extended rows, changing the practical meaning of the join.

❓
Preserve optional matches carefully

A LEFT JOIN to Orders keeps customers without orders. But WHERE o.Status = 'Open' removes rows where o.Status is NULL, so customers without orders disappear.

Core ideas

  • LEFT JOIN preserves unmatched left rows
  • Missing right-side values become NULL
  • WHERE can filter those NULL-extended rows away
  • Place right-side conditions according to business intent
ON vs WHERE
-- Preserves customers with no OPEN orders
SELECT c.CustomerID, o.OrderID
FROM dbo.Customer AS c
LEFT JOIN dbo.Orders AS o
  ON o.CustomerID = c.CustomerID
 AND o.Status = 'Open';

-- This removes customers with no order:
SELECT c.CustomerID, o.OrderID
FROM dbo.Customer AS c
LEFT JOIN dbo.Orders AS o
  ON o.CustomerID = c.CustomerID
WHERE o.Status = 'Open';
✅

With outer joins, predicate location is part of the result logic — not just formatting.

Practice — 3 cases

Practice 10 / Práctica 10
What happens to unmatched right-side columns in a LEFT JOIN?
Practice 11 / Práctica 11
Why can moving a right-table filter from ON to WHERE change a LEFT JOIN into inner-join-like behavior?
Practice 12 / Práctica 12
Where should a filter on the optional right side often go if unmatched left rows must be preserved?
MODULE 05
📊

Aggregates and NULL: COUNT(*) Is Not COUNT(Column)

Most aggregates ignore NULL inputs. That is useful, but it can also hide missing data if you assume NULL equals zero.

❓
Missing is not zero

An average salary over non-NULL salaries answers a different question than an average where missing salaries are treated as zero.

Core ideas

  • COUNT(*) counts rows
  • COUNT(Column) counts non-NULL values
  • SUM/AVG ignore NULL inputs
  • Replacing NULL with zero changes business meaning
Aggregate differences
SELECT
    COUNT(*) AS TotalRows,
    COUNT(Salary) AS RowsWithSalary,
    AVG(Salary) AS AvgKnownSalary,
    AVG(COALESCE(Salary,0)) AS AvgTreatMissingAsZero
FROM dbo.Employee;
✅

Before using COALESCE in aggregates, decide whether missing really means zero in the business process.

Practice — 3 cases

Practice 13 / Práctica 13
How does COUNT(ColumnName) treat NULL values?
Practice 14 / Práctica 14
How does COUNT(*) treat rows containing NULL?
Practice 15 / Práctica 15
How do SUM and AVG generally treat NULL inputs?
MODULE 06
🧰

COALESCE and ISNULL: Useful, but Not Neutral

COALESCE and ISNULL are useful for presenting fallback values, but substituting a value for NULL changes semantics. Missing and zero, missing and empty string, or missing and 'Unknown' are not always interchangeable.

❓
Fallbacks are business decisions

Displaying NULL City as 'Unknown' may be fine for a report. Using COALESCE(City,'') in a join or uniqueness rule may create very different behavior.

Core ideas

  • COALESCE returns first non-NULL expression
  • ISNULL is SQL Server-specific and has its own type behavior
  • Fallback values can collapse distinct business states
  • Use presentation defaults differently from matching logic
Presentation vs logic
-- Presentation fallback
SELECT COALESCE(City, 'Unknown') AS DisplayCity
FROM dbo.Customer;

-- Be careful using the same pattern in predicates:
WHERE COALESCE(City, '') = @City;
✅

Use COALESCE/ISNULL intentionally: they are transformations, not invisible NULL erasers.

Practice — 3 cases

Practice 16 / Práctica 16
What does COALESCE return?
Practice 17 / Práctica 17
What is one difference between ISNULL and COALESCE in SQL Server?
Practice 18 / Práctica 18
What is the main caution when replacing NULL with a default value?
MODULE 07
🧱

NULL in Constraints, Uniqueness and Data Modeling

NULL semantics affect schema design too. Optional attributes that must be unique when present require more thought than simply adding a generic UNIQUE constraint.

❓
Optional but unique is a real business rule

A system may allow missing ExternalID, but if ExternalID is present it must be unique. A filtered unique index can express that rule cleanly.

Core ideas

  • Nullability is part of schema semantics
  • Optional + unique often needs filtered uniqueness
  • Constraints should reflect business meaning
  • Do not rely on application-only NULL assumptions
Optional but unique
CREATE UNIQUE INDEX UX_Customer_ExternalID
ON dbo.Customer(ExternalID)
WHERE ExternalID IS NOT NULL;
✅

Schema-level NULL rules make data quality enforceable instead of merely conventional.

Practice — 3 cases

Practice 19 / Práctica 19
Can a UNIQUE constraint/index in SQL Server allow NULL?
Practice 20 / Práctica 20
What is a useful way to enforce uniqueness only for non-NULL values?
Practice 21 / Práctica 21
Why must NULL behavior be considered in constraints?
MODULE 08
🏭

Production NULL Checklist: Model Missing Data Deliberately

NULL problems are rarely syntax problems alone. They come from unclear business meaning: unknown, not applicable, not yet captured, intentionally absent or failed to load may all deserve different treatment.

❓
The right NULL rule begins before the query

If NULL means three different things in the same column, no clever predicate can fully recover the lost semantics.

Core ideas

  • Define what NULL means per column
  • Use IS NULL / IS NOT NULL explicitly
  • Prefer NOT EXISTS for NULL-safe anti-matching
  • Test aggregates, joins and constraints with NULL edge cases
Production checklist
1. What does NULL mean in this column?
2. Is NULL different from zero / empty / unknown label?
3. Are predicates using IS NULL / IS NOT NULL?
4. Could NOT IN receive NULLs?
5. Could a LEFT JOIN WHERE filter remove unmatched rows?
6. Are COUNT(*) and COUNT(col) being interpreted correctly?
7. Does COALESCE/ISNULL change business meaning?
8. Are optional-unique rules enforced correctly?
9. Have NULL edge cases been tested explicitly?
10. Are application parameter types / defaults consistent with DB nullability?
✅

NULL becomes manageable when missing data has explicit meaning and SQL logic reflects that meaning.

Practice — 3 cases

Practice 22 / Práctica 22
What is the strongest way to test NULL-sensitive SQL?
Practice 23 / Práctica 23
What is the safest anti-join default when NULLs may exist?
Practice 24 / Práctica 24
What is the strongest production rule for NULL semantics?
5-Question Knowledge Check

Can you reason correctly about NULL?

Open each item after answering it in your own words. The 24 interactive practices above drive certificate progress.

1. Why does SQL need UNKNOWN?

Because missing information prevents some comparisons from being known as TRUE or FALSE.

2. Why is = NULL wrong for NULL testing?

Equality with NULL evaluates UNKNOWN; use dedicated NULL predicates.

3. Why is NOT EXISTS safer than NOT IN when NULLs are possible?

NOT EXISTS avoids the classic NULL contamination problem of NOT IN.

4. What is the difference between COUNT(*) and COUNT(Column)?

COUNT(*) counts rows; COUNT(Column) counts non-NULL values.

5. Why can a LEFT JOIN filter in WHERE remove unmatched rows?

Unmatched right-side values are NULL, so WHERE may filter those rows out.

NULL Semantics Quick Map

Patterns worth remembering

SituationSafer pattern
Column = NULLColumn IS NULL
Column <> NULLColumn IS NOT NULL
NOT IN (nullable subquery)NOT EXISTS
Optional right-side filter in LEFT JOINConsider placing it in ON to preserve unmatched left rows
COUNT(*) vs COUNT(col)Remember: rows vs non-NULL values

Certificate of Participation

Complete at least 12 of the 24 practice cases (50%) and enter your name.

0 / 24 • 0%
Production note

NULL semantics are a data-modeling concern and a query-logic concern at the same time.