La seguente query restituisce 2036 righe:Sono pazzo: PostgreSQL IN all'operatore di query nidificate restituire risultati inattesi
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
Ma la seguente dichiarazione unica aggiornato 1870 Righe:
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
)
come è possibile ?
MODIFICA 1: La prima query continua a restituire 166 righe e la seconda continua ad aggiornare 0 righe.
EDIT 2:
Nel seguito, l'interrogazione nidificata restituisce una riga contenente un UID, ma query esterna restituisce 0 righe.
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
)
Sono pazzo?
EDIT 3:
l'istruzione che segue, fornito da @wildplasser è riuscito a aggiornare i restanti 166 righe:
UPDATE "Foo" ff
SET "BarUID" = 'aNewUID'
WHERE ff."BarUID" IS NOT NULL
AND NOT EXISTS (
SELECT * FROM "Bar" bb
WHERE bb."BarUID"= ff."BarUID"
)
Tuttavia, ancora non capisco perché l'originale non ha preso loro. Se la query nidificata è stata selezionata 166 "FooUID"
s, perché non dovrebbero corrispondere alle righe nella tabella "Foo"
utilizzando IN
?
EDIT 4: Più ci penso, questo scenario potrebbe essere importante:
Tutto questo ha avuto luogo su un server di database che è stato recentemente clonato da un altro. Ho parlato con il tizio IT che ha fatto la clonazione, e si scopre che non ha chiuso un'applicazione in esecuzione sul DB originale prima di ridurla per clonarla. Ciò significa che il DB è stato per lo più probabilmente abbattuto a metà transazione (non so quanto vergognosamente). È possibile che qualcosa nel database sia stato lasciato in uno stato corrotto, portandomi a vedere queste righe fantasma?
Sfortunatamente non riesco più a ripeterlo, da quando è in esecuzione la correzione di wildplasser. Il DB originale (di nuovo disponibile e in grado di servire l'applicazione) non ha nessuno dei dati non validi che stavo cercando di correggere sulla copia, tanto meno nessuna traccia degli shenanigans che ho visto.
Devo dire che prima di eseguire la correzione, ho ridotto la questione al l'assurdità più elementare: in primo luogo ho scelto il FooUID
dalla query nidificate in Modifica 2, copiato negli appunti, poi corse una query scegliendo tra Foo
dove FooUID
uguale al valore incollato - questo è ancora ha restituito 0 righe.
Che tipo è 'FooUID' e quale viene restituito dalla query interna in EDIT 2? Non ho idea di cosa stia succedendo, solo spiando un po '. –
@mu è troppo breve - 'FooUID' è di tipo' uuid'. Non sono sicuro di aver capito la seconda parte della tua domanda. –
Il tuo EDIT 2 mi ha bloccato. Deve essere un valore che non è paragonabile a se stesso. Sei sicuro che la parte interna restituisca un 'FooUID 'non Null? –