News for hackers. Stuff that matters.
Re:Postgres 15 improves UNIQUE and NULL by jeff-davis on Monday July 11, 2022 @01:46PM (#32059283)
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!
Re:Postgres 15 improves UNIQUE and NULL by masklinn on Tuesday July 12, 2022 @01:33AM (#32066040)
I’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.