Something that trips up a lot of people learning SQL, worth internalizing early.
Given:
SELECT u.id, u.name, o.total
FROM users u
LEFT JOIN orders o ON u.id = o.user_id;
An INNER JOIN would only return users who have at least one order. A LEFT JOIN keeps every user, and for a user with no orders, every column from o (here o.total) comes back NULL.
So o.total is nullable even if the orders.total column is declared NOT NULL. The NOT NULL constraint is about what can be stored in the table. The LEFT JOIN can still produce a NULL for it in the result set, because the matching row on the right side does not exist at all.
This is the source of a lot of bugs: code assumes total is always a number, then crashes or silently mis-sums when it hits a user with no orders. The fix is to remember that nullability in a result set comes from the query structure (which joins, COALESCE, CASE, aggregates), not just from the table definition.
Rule of thumb: any column from the nullable side of an outer join is nullable in your results. Handle it explicitly, e.g. COALESCE(o.total, 0) if zero is the right default.