Następująca kwerenda zwraca 2036 wierszy:jestem szalony: PostgreSQL oraz operatora z zagnieżdżonych zapytań powrocie nieoczekiwane rezultaty
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
Ale następujące oświadczenie aktualizowane tylko 1870 wierszy:
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
)
Jak to możliwe ?
EDYCJA 1: Pierwsze zapytanie nadal zwraca 166 wierszy, a drugie kontynuuje aktualizację 0 wierszy.
EDIT 2:
Poniżej zapytanie zagnieżdżone zwraca się wiersz zawierający UID, a zapytanie zewnętrznej zwraca 0 wierszy.
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
)
Czy jestem szalony?
EDIT 3:
następujące oświadczenie, dostarczone przez @wildplasser udało się aktualizację pozostałych 166 rzędów:
UPDATE "Foo" ff
SET "BarUID" = 'aNewUID'
WHERE ff."BarUID" IS NOT NULL
AND NOT EXISTS (
SELECT * FROM "Bar" bb
WHERE bb."BarUID"= ff."BarUID"
)
Jednak ja nadal nie rozumiem, dlaczego nie wybrać oryginalny ich. Jeśli zapytanie zagnieżdżone zostało wybrane 166 "FooUID"
s, dlaczego nie byłyby one dopasowane do wierszy tabeli "Foo"
przy użyciu IN
?
EDIT 4: Im więcej o tym myślę, to tło może być ważne:
To wszystko miało miejsce na serwerze bazy danych, który został niedawno sklonowanego z inną. Rozmawiałem z informatykiem, który przeprowadził klonowanie, i okazało się, że nie zamknął aplikacji działającej na oryginalnym DB, zanim zdążył ją sklonować. Oznacza to, że DB został najprawdopodobniej sprowadzony w dół w połowie transakcji (nie wiem, jak bezwstydnie). Czy jest możliwe, że coś w bazie danych zostało w stanie uszkodzonym, prowadząc mnie do tych widmowych wierszy?
Niestety nie mogę już repro, ponieważ działa poprawka wildplasser. Oryginalna DB (ponownie i obsługująca aplikację) nie ma żadnych niepoprawnych danych, które próbowałem naprawić na kopii, a tym bardziej śladu shenaniganów, których byłem świadkiem.
należy wspomnieć, że przed uruchomieniem poprawkę, ja zmniejszona problem do najbardziej podstawowych absurdu: Po raz pierwszy wybrano FooUID
z zapytania zagnieżdżonego w Edit 2, kopiować go do schowka, a następnie prowadził kwerendę Wybieranie z Foo
gdzie FooUID
równa się wklejonej wartości - ta nadal zwróciła 0 wierszy.
Jakiego typu jest 'FooUID' i który jest zwracany przez wewnętrzne zapytanie w EDIT 2? Nie mam pojęcia, co się dzieje, tylko trochę pogrzebać. –
@mu jest za krótki - 'FooUID' to typ' uuid'. Nie jestem pewien, czy rozumiem drugą część twojego pytania. –
Twoja EDIT 2 mnie zaskoczyła. Musi to być wartość, która nie równa się sama. Jesteś pewny, że wewnętrzna część zwraca nie-NULL 'FooUID'? –