3 ms·
In any thread involving SQL NULL, I see a lot of not-quite-right explanations of what SQL NULL is, conceptually. I challenge anyone who feels like they understa
by jeff-davis 4y ago
In any thread involving SQL NULL, I see a lot of not-quite-right explanations of what SQL NULL is, conceptually. I challenge anyone who feels like they understand NULL conceptually to explain the following query:
-- find orders with a total less than $10000
select order_id, sum(price)
from orders o left join order_lineitems l using (order_id)
group by order_id having sum(price) < 10000;
This query is actually incorrect. Orders with no line items at all are clearly less than $10000, but they will be excluded because: first, the left outer join produces a NULL for the price; second, the group aggregation with SUM over that NULL will result in NULL; and third, the HAVING clause treats that NULL as false-like and excludes the order from the result.
Of course, we can explain procedurally what's happening here, and each individual step makes some sense. But the end result has no conceptual integrity.
Extra challenge: explain why using COUNT instead of SUM in the query does correctly return orders with fewer than 4 items:
-- find orders with fewer than 4 line items
select order_id, count(price)
from orders o left join order_lineitems l using (order_id)
group by order_id having count(price) < 4;
PS: thank you to the author for a developer-friendly feature that adds flexibility here!
- masklinn 4y agoI’m not sure what explanation you want, NULL is in essence “not a value”, which works more or less the same way “not a number” does. So yes if you perform operations between a NULL and a value you get a NULL, therefore when you sum or compare NULLs with or to other things you get NULL, which is then treated as false in a boolean context. If the price of one item is UNKNOWN (which is what NULL represents in SQL) then it stands to reason that the sum is unknown, and it is unknown whether the sum is or is not smaller than 10000. > But the end result has no conceptual integrity. > Pray, Mr. Babbage, if you put into the machine wrong figures, will the right answers come out? > Extra challenge: explain why using COUNT instead of SUM in the query does correctly return orders with fewer than 4 items: You don’t need to determine the values of the sequence to see that there are 4 of them, therefore count doesn’t care that some of the items are null.