我需要UPDATE这样使用:
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 ;
Run Code Online (Sandbox Code Playgroud)
但我得到以下信息:
错误:对表“offer”的 FROM 子句条目的引用无效
提示:表“offer”有一个条目,但不能从查询的这部分引用它。
先感谢您
当使用这种形式的查询时:UPDATE a SET columns=values FROM b WHERE ...,b子查询的计算独立于a,并且查询末尾的 WHERE 块应该连接 和 的a行b。
问题中的查询尝试在子查询内部连接,而不是在最上层的 WHERE 子句中连接(实际上它没有这样的 WHERE 子句),但这是不允许的,这就是错误消息所指示的。
使用相关子查询更新每一行的 SQL 标准方法是:
UPDATE a SET (col1,col2) =
(SELECT val1,val2 FROM b WHERE expression-needing-values-from-a)
Run Code Online (Sandbox Code Playgroud)
但在旧版本的 PostgreSQL(9.4 或之前)中,手册明确告知这种形式没有实现。从9.5开始,实现了。
使用 postgres 9.4 模拟它的典型方法是在子查询中使用表的副本a,并在上层的 WHERE 子句中连接回更新的表,如下所示:
UPDATE a SET (col1,col2)=(s.col1,s.col2)
FROM (SELECT a2.ctid,col1,col2 AS ctid_of_row FROM b, a AS a2 WHERE...) AS s
WHERE s.ctid_of_row = a.ctid;
Run Code Online (Sandbox Code Playgroud)
知道这ctid是系统伪列,指示行版本在其表中的物理位置。或者,如果有主键,则可以使用主键。
在您的情况下,转换并不明显,因为您的子查询旨在仅生成一行及其ORDER BY... LIMIT 1末尾。应该重新设计它以在单个结果集中生成所有目标行,大概(verticeid,cost,gid)是cost根据gid确定的offer.verticeid。