如何更新使用三个表JOIN

时间:2017-06-29 18:17:07

标签: sql postgresql

我确实使用旧式表示法使其工作。

DBFiddle

UPDATE
    route_sources rs
SET
    has_route = false
FROM avl a1, avl a2 
WHERE rs.avl_id_begin = a1.avl_id
  AND rs.avl_id_end = a2.avl_id 
  AND 0 IN (a1.azimuth, a2.azimuth)

但是想知道是否可以使用显式连接sintaxis写入:

UPDATE
    route_sources rs
SET
    has_route = false
FROM avl a1
JOIN avl a2 
  ON rs.avl_id_end = a2.avl_id   <= this doesnt work
WHERE rs.avl_id_begin = a1.avl_id
  AND 0 IN (a1.azimuth, a2.azimuth)
  

错误:引用la la lala la la lalalala来自para la tabla«rs»noválida
  第10行:开启rs.avl_id_end = a2.avl_id
                ^
  提示:Hay una entrada para la tabla«rs»,pero no puede ser referenciada desde esta parte de la consulta。

翻译成类似的东西。

rs clausule中对FROM的引用无效。提示:rs有一个条目,但无法参考查询的这一部分。

同时尝试使用全名而不是别名,但两者都不起作用。

2 个答案:

答案 0 :(得分:0)

一种方法是使用子查询/ cte选择行,然后加入目标表:

WITH cte AS ( 
  SELECT rs.route_source_id 
  FROM route_sources rs 
  JOIN avl a1 ON rs.avl_id_begin = a1.avl_id 
  JOIN avl a2 ON rs.avl_id_end = a2.avl_id 
  WHERE 0 IN (a1.azimuth, a2.azimuth)
) 
UPDATE route_sources rt 
SET has_route = false 
FROM cte c 
WHERE c.route_source_id = rt.route_source_id;

或:

UPDATE route_sources rt 
SET has_route = false 
FROM (SELECT rs.route_source_id 
      FROM route_sources rs 
      JOIN avl a1 ON rs.avl_id_begin = a1.avl_id 
      JOIN avl a2 ON rs.avl_id_end = a2.avl_id 
      WHERE 0 IN (a1.azimuth, a2.azimuth)) s 
WHERE s.route_source_id = rt.route_source_id;

LiveDemo

答案 1 :(得分:0)

重点是a1和a2没有关联(仅通过rs) 这可能更简单(也更快)。它还会避免对同一行进行多次更新。

UPDATE route_sources rs
SET has_route = false
WHERE EXISTS( SELECT* FROM avl a1 
        WHERE a1.avl_id= rs.avl_id_begin 
        AND a1.azimuth =0
        )
OR EXISTS (SELECT* FROM avl a2 
        WHERE a2.avl_id = rs.avl_id_end
        AND a2.azimuth= 0
        );