在 PostgreSQL 中具有多个连接的 UPDATE 语句

UPDATE statement with multiple joins in PostgreSQL

我正在尝试更新名为 incode_warrants 的 table 并将 warn_docket_noincode_violations table 设置为 viol_docket_no .

我在 Postgres 9.3 中有以下 SQL 查询,但是当它触发时我收到以下错误:

Error : ERROR:  relation "iw" does not exist
LINE 1: update iw

我更像是一个 Active Record 的人,所以我的原始 SQL 技能严重缺乏。我想知道是否有人可以帮助我指明正确的方向,了解如何正确执行此查询。

update iw
set iw.warn_docket_no = iv.viol_docket_no
from incode_warrants as iw
INNER JOIN incode_warrantvs as iwvs
on iw.warn_rid = iwvs.warnv_rid
INNER JOIN incode_violations as iv
ON iv.viol_citation_no = iwvs.warnv_citation_no and iv.viol_viol_no = iwvs.warnv_viol_no

你的更新是table,不是加入

update incode_warrants ALIAS
set warn_docket_no = iv.viol_docket_no
from incode_warrantvs as iw 
...

您的查询应如下所示:

UPDATE incode_warrants
SET warn_docket_no = incode_violations.viol_docket_no
FROM incode_violations
WHERE incode_violations.viol_citation_no = incode_warrants.warnv_citation_no
AND incode_violations.viol_viol_no = incode_warrants.warnv_viol_no;

您不需要任何其他加入。使用此查询,您只需使用另一个 table 的列中的值更新一个 table 中的列。当然,它只有在 WHERE 条件为真时才会更新。

与 Postgres 中的有效 UPDATE 语句相同:

UPDATE incode_warrants iw
SET    warn_docket_no = iv.viol_docket_no
FROM   incode_warrantvs  iwvs
JOIN   incode_violations iv ON iv.viol_citation_no = iwvs.warnv_citation_no
                           AND iv.viol_viol_no = iwvs.warnv_viol_no
WHERE  iw.warn_rid = iwvs.warnv_rid;
-- AND iw.warn_docket_no IS DISTINCT FROM iv.viol_docket_no -- see below

您不能只在 FROM 子句中使用 table 别名作为 UPDATE 子句中的目标 table。要更新的(一个!)table 紧跟在 UPDATE 关键字之后(如果我们忽略中间可能存在的 ONLY 关键字)。如果需要,您可以在那里添加别名。这是您的错误消息的直接原因,但还有更多。

要更新的列始终来自要更新的 table,不能是 table 限定的。

您不需要在 FROM 子句中重复目标 table - 除了像这样的特殊情况:

  • PostgreSQL: update with left outer self join ignored

这个可选的添加可以通过抑制不改变任何内容的更新来避免无意义的成本:

AND iw.warn_docket_no IS DISTINCT FROM iv.viol_docket_no

参见:

  • How do I (or can I) SELECT DISTINCT on multiple columns?

More in the excellent manual on UPDATE.

UPDATE incode_warrants iw
     SET warn_docket_no = iv.viol_docket_no
FROM incode_warrantvs AS iwvs, incode_violations AS iv 
WHERE iv.viol_citation_no = iwvs.warnv_citation_no AND
      iv.viol_viol_no = iwvs.warnv_viol_no AND
      iw.warn_rid = iwvs.warnv_rid;

那是我的代码,我在 a 中生成了我的连接和附件,在连接之后与我的可更新 table 以及在我比较我的身份的地方,对不起我的英语

update cs_ticket ct
set site_name = a.name
from (
    select ct.id, cs."name" 
    from cs_ticket ct 
    inner join cs_net_segment cns 
    on ct.affected_ip like cns.ip || '.%'
    and end_date is null
    inner join cs_site cs 
    on cs.id = cns.site_id)a
where ct.id = a.id;