Следующий запрос возвращает 2036 строк:
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
Но следующий оператор обновил только 1870 строк:
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
)
Как это возможно?
РЕДАКТ. 1: Первый запрос продолжает возвращать 166 строк, а второй продолжает обновлять 0 строк.
РЕДАКТИРОВАТЬ 2:
В дальнейшем вложенный запрос возвращает строку, содержащую UID, но внешний запрос возвращает 0 строк.
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
)
Я сумасшедший?
РЕДАКТИРОВАТЬ 3:
Следующий оператор, предоставленный @ wildplasser , обновил оставшиеся 166 строк:
UPDATE "Foo" ff
SET "BarUID" = 'aNewUID'
WHERE ff."BarUID" IS NOT NULL
AND NOT EXISTS (
SELECT * FROM "Bar" bb
WHERE bb."BarUID"= ff."BarUID"
)
Однако я до сих пор не понимаю, почему оригинал их не взял. Если во вложенном запросе выбрано 166 "FooUID"
с, почему бы не сопоставить их со строками таблицы "Foo"
, используя IN
?
РЕДАКТИРОВАТЬ 4: Чем больше я думаю об этом, этот фон может быть важным:
Все это происходило на сервере базы данных, который был недавно клонирован с другого. Я поговорил с ИТ-специалистом, который выполнял клонирование, и выяснилось, что он не закрывал приложение, работающее поверх исходной БД, перед тем, как его клонировать. Это означает, что БД, скорее всего, была сбита в середине транзакции (я не знаю, насколько неблагодарно). Возможно ли, что что-то в базе данных было повреждено, что заставило меня увидеть эти фантомные строки?
К сожалению, я больше не могу его воспроизвести, так как запустил исправление wildplasser. В исходной БД (снова запущенной и обслуживающей приложение) нет ни одной недопустимой информации, которую я пытался исправить в копии, и тем более никаких следов махинаций, свидетелем которых я был.
Я должен упомянуть, что перед запуском исправления я довел проблему до самого простого абсурда: сначала я выбрал FooUID
из вложенного запроса в Edit 2, скопировал его в буфер обмена, затем запустил запрос, выбирая из Foo
, где FooUID
равно вставленному значению - это still вернуло 0 строк.