<pre>sqlite> .mode table sqlite> SELECT a67.c7 > a67.c9 FROM v1 AS a67; +-----------------+ | a67.c7 > a67.c9 | +-----------------+ | | | | +-----------------+</pre> It produces two NULL rows, which is not the same as producing no rows. Both of those rows are TRUE, in that they each have a column. Next, <pre>sqlite> SELECT * FROM v0 AS a66 WHERE EXISTS ( SELECT a67.c7 > a67.c9 FROM v1 AS a67 WHERE a66.c3 = a67.c10 AND a66.c3 IS a67.c6 ); +----+----+----+-----+-----+ | c1 | c2 | c3 | c4 | c5 | +----+----+----+-----+-----+ | 1 | | 0 | 100 | 200 | +----+----+----+-----+-----+</pre> gives you one row. Which is correct. And therefore your full line gives you one row. SQLite seems to be interpreting this horrible piece of SQL in a reasonable way, and getting a reasonable result. I don't think the result is technically wrong. Just different to what an earlier version got.