简体   繁体   中英

postgresql 9.6:issue with UPDATE

I'm stuck with an UPDATE, probably I'm messing something up:

the amount of rows in the ' proj_los ' table expected to be updated are 32, but only 8 get updated, unless I add an AND condition.

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

1) correct result -> using last AND clause ( 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) wrong result

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

Any help on this?

You hit the problem described in the postgres documentation of UPDATE ... FROM ... :

When using FROM you should ensure that the join produces at most one output row for each row to be modified. In other words, a target row shouldn't join to more than one row from the other table(s). If it does, then only one of the join rows will be used to update the target row, but which one will be used is not readily predictable

If the additional filter by root_id is not specified the query on which the update is based upon most probably returns multiple rows for every updated row. Some unpredictable row is used to do the update. And what must have happened is that in many cases incorrect root_id had been used.

Note how update modified 174202 rows (and not 8 rows as you written). It updated root_id s in unrelated records that you do not want to be updated.

So check import.tmp_kk table. It contains more then one record (with different root_id s) for given lo_id .

I dont understand: I said that the correct result would be an update or 32 rows instead of 8 for that root_id.

of course import.tmp_kk contains more than a lo_id for a single root_id , on the target table proj_los , lo_root_id will be a FK for lo_id .

For what concern the postgres docs, to me it seems that it says essentially to make sure that there's no dupes in the result joined table:

"When using FROM you should ensure that the join produces at most one output row for each row to be modified."

so I checked with:

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;

but there's no results:

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

Can you or someone else please tell me how to modify the UPDATE statement in order to achieve the correct result?

Thanks

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM