首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在PostgreSQL中执行更新+ join?

如何在PostgreSQL中执行更新+ join?
EN

Stack Overflow用户
提问于 2011-10-24 06:09:23
回答 7查看 450.1K关注 0票数 614

基本上,我想这样做:

代码语言:javascript
复制
update vehicles_vehicle v 
    join shipments_shipment s on v.shipment_id=s.id 
set v.price=s.price_per_vehicle;

我非常确定这在MySQL (我的背景)下是可行的,但在postgres中似乎行不通。我得到的错误是:

代码语言:javascript
复制
ERROR:  syntax error at or near "join"
LINE 1: update vehicles_vehicle v join shipments_shipment s on v.shi...
                                  ^

当然,有一种简单的方法可以做到这一点,但我找不到合适的语法。那么,我该如何用PostgreSQL编写这段代码呢?

EN

回答 7

Stack Overflow用户

发布于 2015-07-30 16:37:12

在这种情况下,Mark Byer的答案是最优的。不过,在更复杂的情况下,您可以使用返回rowids和计算值的select查询,并将其附加到更新查询,如下所示:

代码语言:javascript
复制
with t as (
  -- Any generic query which returns rowid and corresponding calculated values
  select t1.id as rowid, f(t2, t2) as calculatedvalue
  from table1 as t1
  join table2 as t2 on t2.referenceid = t1.id
)
update table1
set value = t.calculatedvalue
from t
where id = t.rowid

这种方法允许您开发和测试select查询,并通过两个步骤将其转换为update查询。

因此,在您的示例中,结果查询将为:

代码语言:javascript
复制
with t as (
    select v.id as rowid, s.price_per_vehicle as calculatedvalue
    from vehicles_vehicle v 
    join shipments_shipment s on v.shipment_id = s.id 
)
update vehicles_vehicle
set price = t.calculatedvalue
from t
where id = t.rowid

请注意,列别名是强制的,否则PostgreSQL将报告列名的多义性。

票数 183
EN

Stack Overflow用户

发布于 2013-07-24 08:11:07

让我用我的例子进一步解释一下。

任务:更正信息,其中申请人(即将离开中学的学生)提交大学申请的时间早于获得学校证书的时间(是的,他们获得证书的时间早于颁发证书的时间(在指定的证书日期之前)。因此,我们将增加申请提交日期以适应证书颁发日期。

因此。下一条类似MySQL的语句:

代码语言:javascript
复制
UPDATE applications a
JOIN (
    SELECT ap.id, ab.certificate_issued_at
    FROM abiturients ab
    JOIN applications ap 
    ON ab.id = ap.abiturient_id 
    WHERE ap.documents_taken_at::date < ab.certificate_issued_at
) b
ON a.id = b.id
SET a.documents_taken_at = b.certificate_issued_at;

以这样的方式变得像PostgreSQL

代码语言:javascript
复制
UPDATE applications a
SET documents_taken_at = b.certificate_issued_at         -- we can reference joined table here
FROM abiturients b                                       -- joined table
WHERE 
    a.abiturient_id = b.id AND                           -- JOIN ON clause
    a.documents_taken_at::date < b.certificate_issued_at -- Subquery WHERE

正如你所看到的,原始子查询JOINON子句已经变成了WHERE条件之一,它是由AND和其他条件连接在一起的,这些条件从子查询中移出而没有任何变化,并且不再需要像在子查询中那样对表本身进行JOIN

票数 175
EN

Stack Overflow用户

发布于 2014-05-09 12:56:44

对于那些真正想要做JOIN的人,你也可以使用:

代码语言:javascript
复制
UPDATE a
SET price = b_alias.unit_price
FROM      a AS a_alias
LEFT JOIN b AS b_alias ON a_alias.b_fk = b_alias.id
WHERE a_alias.unit_name LIKE 'some_value' 
AND a.id = a_alias.id;

如果需要,您可以在等号右侧的SET部分中使用a_alias。等号左边的字段不需要表引用,因为它们被认为来自原始的"a“表。

票数 113
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7869592

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档