Note that there are some explanatory texts on larger screens.

plurals
  1. POAm I crazy: PostgreSQL IN operator with nested query returning unexpected results
    primarykey
    data
    text
    <p>The following query returns 2036 rows:</p> <pre><code>SELECT "FooUID" from "Foo" f LEFT JOIN "Bar" b ON f."BarUID" = b."BarUID" WHERE f."BarUID" IS NOT NULL AND b."BarUID" IS NULL </code></pre> <p>But the following statement only updated 1870 rows:</p> <pre><code>UPDATE "Foo" f1 set "BarUID" = 'aNewUID' WHERE f1."FooUID" IN ( SELECT f2."FooUID" from "Foo" f2 LEFT JOIN "Bar" b ON f2."BarUID" = b."BarUID" WHERE f2."BarUID" IS NOT NULL AND b."BarUID" IS NULL ) </code></pre> <p>How is this possible?</p> <p><strong>EDIT 1:</strong> The first query continues to return 166 rows, and the second continues to update 0 rows.</p> <p><strong>EDIT 2:</strong></p> <p>In the following, the nested query returns a row containing a UID, but the outer query returns 0 rows.</p> <pre><code>SELECT * from "Foo" f1 WHERE f1."FooUID" = ( SELECT f2."FooUID" FROM "Foo" f2 LEFT JOIN "Bar" b ON f2."BarUID" = b."BarUID" WHERE f2."BarUID" IS NOT NULL AND b."BarUID" IS NULL LIMIT 1 ) </code></pre> <p>Am I crazy?</p> <p><strong>EDIT 3:</strong></p> <p>The following statement, provided by <a href="https://stackoverflow.com/users/905902/wildplasser">@wildplasser</a> succeeded in updating the remaining 166 rows:</p> <pre><code>UPDATE "Foo" ff SET "BarUID" = 'aNewUID' WHERE ff."BarUID" IS NOT NULL AND NOT EXISTS ( SELECT * FROM "Bar" bb WHERE bb."BarUID"= ff."BarUID" ) </code></pre> <p>However, I still don't understand why the original didn't pick them up. If the nested query selected 166 <code>"FooUID"</code>s, why would they not be matched to rows in the <code>"Foo"</code> table using <code>IN</code>?</p> <p><strong>EDIT 4:</strong> The more I think about it, this background might be important: </p> <p>This all took place on a database server that was recently cloned from another one. I spoke to the IT guy who did the cloning, and it turns out he didn't shut down an application running on top of the original DB before bringing it down to clone it. This means the DB was mostly likely brought down mid-transaction (I don't know how ungracefully). Is it possible something in the database was left in a corrupted state, leading me to see these phantom rows? </p> <p>Unfortunately I can no longer repro it, since running wildplasser's fix. The original DB (up and serving the application again) has none of the invalid data I was trying to fix on the copy, much less any trace of the shenanigans I witnessed.</p> <p>I should mention that before running the fix, I reduced the issue to the most basic absurdity: I first selected the <code>FooUID</code> from the nested query in Edit 2, copied it to the clipboard, then ran a query selecting from <code>Foo</code> where <code>FooUID</code> equaled the pasted value - this <em>still</em> returned 0 rows.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload