postgresql 9.6: проблема с обновлением - PullRequest
0 голосов
/ 05 октября 2018

Я застрял с UPDATE, возможно, я что-то напутал:

количество строк в таблице 'proj_los', которые должны быть обновлены, равно 32, но обновляются только 8,если только я не добавлю условие AND.

select count(*) from import.tmp_kk where root_id = '57b2e67b-5862-499a-a471-0f2f6b23440e';
> 32

1) правильный результат -> использование последнего предложения AND (root_id = '57b2e67b-5862-499a-a471-0f2f6b23440e')

sql> update
       proj_los as oko
       set lo_root_id = import.tmp_kk.root_id
       from import.tmp_kk
       where oko.lo_id = import.tmp_kk.lo_id
       and import.tmp_kk.root_id = '57b2e67b-5862-499a-a471-0f2f6b23440e'
[2018-10-05 18:13:59] 32 rows affected in 50 ms


select count(*) from proj_los where lo_root_id = '57b2e67b-5862-499a-a471-0f2f6b23440e';

> 32

2) неправильный результат

sql> update
         proj_los as oko
       set lo_root_id = import.tmp_kk.root_id
       from import.tmp_kk
       where oko.lo_id = import.tmp_kk.lo_id;
[2018-10-05 18:17:31] 174202 rows affected in 17 s 427 ms

select count(*) from proj_los where lo_root_id = '57b2e67b-5862-499a-a471-0f2f6b23440e';

> 8

Любая помощь в этом?

Ответы [ 2 ]

0 голосов
/ 05 октября 2018

Я не понимаю: я сказал, что правильным результатом будет обновление или 32 строки вместо 8 для этого root_id.

конечно import.tmp_kk содержит более lo_id для одного root_id, на целевой таблице proj_los, lo_root_id будет FK для lo_id.

Что касается документации postgres, мне кажется, что она говорит, по сути, чтобы убедиться, что нет дубликатовв таблице результатов объединения:

"При использовании FROM необходимо убедиться, что объединение создает не более одной выходной строки для каждой строки, подлежащей изменению."

, поэтому я проверил:

with tmp_joinres as (
    select oko.lo_id, gg.root_id
    from proj_los oko
    full outer join import.tmp_kk gg on oko.lo_id = gg.lo_id
)
    select tmp_joinres.lo_id, tmp_joinres.root_id, count(*)
    from tmp_joinres
    group by tmp_joinres.lo_id, tmp_joinres.root_id
    having count(*) > 1;

но результатов нет:

[2018-10-05 21:58:20] 0 rows retrieved in 5 s 737 ms (execution: 5 s 729 ms, fetching: 8 ms)

Скажите, пожалуйста, как вы или кто-то еще можете изменить выражение UPDATE, чтобы получить правильный результат?

Спасибо

0 голосов
/ 05 октября 2018

Вы столкнулись с проблемой, описанной в документации postgres из UPDATE ... FROM ...:

При использовании FROM убедитесь, что объединение создает не более одной выходной строки для каждой строкибыть измененным.Другими словами, целевая строка не должна соединяться с более чем одной строкой из других таблиц.Если это так, то только одна из строк соединения будет использоваться для обновления целевой строки, но какая из них будет использоваться, трудно предсказать

Если дополнительный фильтр с помощью root_id не указанзапрос, на котором основано обновление, скорее всего, возвращает несколько строк для каждой обновленной строки.Некоторая непредсказуемая строка используется для обновления.И что должно было произойти, так это то, что во многих случаях использовался неправильный root_id.

Обратите внимание, как обновление изменило 174202 строк (а не 8 строк, как вы написали).Он обновил root_id в несвязанных записях, которые вы не хотите обновлять.

Так проверьте import.tmp_kk таблицу.Он содержит более одной записи (с разными root_id с) для данного lo_id.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...