I would need to use UPDATE
like this:
update offer set (bank, bank_id) = (cost, gid)
from (
select cost, osm_points.gid from pgr_kdijkstraCost(
'SELECT gid as id, source, target, walk_cost as cost FROM ways',
offer.vertice_id,
array(select vertice_id from osm_points where super_type = 'bank'),
false,false)
join osm_points on id2 = vertice_id
where cost != -1
and osm_points.super_type = 'bank'
order by cost
limit 1)t ;
but I get following:
ERROR: invalid reference to FROM-clause entry for table "offer"
HINT: There is an entry for table "offer", but it cannot be referenced from this part of the query.
Thank you in advance
Best Answer
When using a query of this form:
UPDATE a SET columns=values FROM b WHERE ...
, theb
subquery is evaluated independently ofa
, and it's the WHERE block at the end of the query that is supposed to join the rows ofa
andb
.The query in the question attempts to join inside the subquery rather than in a WHERE clause at the uppermost level (in fact it doesn't have such a WHERE clause), but it's not allowed and that's what the error message indicates.
The SQL-standard way of updating each row with a correlated subquery would be:
but in older versions of PostgreSQL (9.4 or before), the manual explicitly tells that this form is not implemented. Starting with 9.5, it is implemented.
The typical way to emulate it with postgres 9.4 is to use a copy of table
a
in the subquery and join back to the updated table in the upper level's WHERE clause, like this:knowing that
ctid
is the system pseudo-column that indicates the physical location of the row version within its table. Alternatively, the primary key can be used if there is one.In your case, the transformation is not obvious because your subquery is meant to produce only one row with its
ORDER BY... LIMIT 1
at the end. It should be redesigned to produce all the target rows in a single resultset, presumably(verticeid,cost,gid)
wherecost
andgid
are determined peroffer.verticeid
.