基本上,我想这样做:
update vehicles_vehicle v
join shipments_shipment s on v.shipment_id=s.id
set v.price=s.price_per_vehicle;
我非常确定这在MySQL (我的背景)下是可行的,但在postgres中似乎行不通。我得到的错误是:
ERROR: syntax error at or near "join"
LINE 1: update vehicles_vehicle v join shipments_shipment s on v.shi...
^
当然,有一种简单的方法可以做到这一点,但我找不到合适的语法。那么,我该如何用PostgreSQL编写这段代码呢?
发布于 2015-07-30 16:37:12
在这种情况下,Mark Byer的答案是最优的。不过,在更复杂的情况下,您可以使用返回rowids和计算值的select查询,并将其附加到更新查询,如下所示:
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查询。
因此,在您的示例中,结果查询将为:
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将报告列名的多义性。
发布于 2013-07-24 08:11:07
让我用我的例子进一步解释一下。
任务:更正信息,其中申请人(即将离开中学的学生)提交大学申请的时间早于获得学校证书的时间(是的,他们获得证书的时间早于颁发证书的时间(在指定的证书日期之前)。因此,我们将增加申请提交日期以适应证书颁发日期。
因此。下一条类似MySQL的语句:
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
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
正如你所看到的,原始子查询JOIN
的ON
子句已经变成了WHERE
条件之一,它是由AND
和其他条件连接在一起的,这些条件从子查询中移出而没有任何变化,并且不再需要像在子查询中那样对表本身进行JOIN
。
发布于 2014-05-09 12:56:44
对于那些真正想要做JOIN
的人,你也可以使用:
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“表。
https://stackoverflow.com/questions/7869592
复制相似问题