Radim Marek lays out a common issue people experience in PostgreSQL:
A
NOT INquery can return the wrong answer without telling you. It is valid SQL, it runs without an error, and it hands back a perfectly well-formed result set that happens to be empty when it should not be. No warning, no hint, nothing in the logs: just zero rows where you expected hundreds, and a database that considers it correct.Almost always the cause is a single
NULLsitting somewhere you forgot to look, combined with two keywords you have typed a thousand times:NOT IN. None of it is a Postgres bug. This is exactly what the SQL standard mandates, implemented faithfully. That is precisely what makes it so easy to walk into, and why the planner could not safely optimize around it for the better part of Postgres’s history. It comes down to oneifstatement in the parser.
This is a Postgres-specific problem, as the same code runs successfully in SQL Server. But if you are working with Postgres, it’s good to keep track of this behavior, and Radim has solid advice for a proper workaround.
> This is a Postgres-specific problem
Most definitely is not. SQL Server has the same behavior with NULLs and quite tawdry performance issues with NULLable columns when using NOT IN: https://erikdarling.com/performance-pains-with-not-in-and-nullable-columns-in-sql-server-2/
Agreed that there are performance issues. I was talking about how, up until Postgres 19 comes out, results are incorrect.