【问题标题】:Postgres UPDATE FROM set value according to result of other queryPostgres UPDATE FROM 根据其他查询的结果设置值
【发布时间】:2015-05-12 21:06:06
【问题描述】:

我被UPDATE 卡住了。我的表格最初是:

Clients
------------------
ID
Emails
Notification_type

Contracts
------------------
ID
Client_id (FK)

Contracts_document_types
------------------
Contract_id (FK)
Document_type_id (FK)

我可以根据Clients 表进行通知。然后我不得不更改通知方法。我的数据库更改为:

Contracts_document_types
------------------
Contract_id (FK)
Document_type_id (FK)
Notification_method_id (FK)

Notification_methods
------------------
ID
emails
notification_type

我能够根据客户创建必要的notification_methods 条目,但我没有找到在contracts_document_types.notification_method_id 中关联的方法。可以根据clients 表找到notification_method,但是要更新的表是contracts_document_types,我不知道如何。

我的想法是这样的:

update contracts_document_types
set notification_method_id = query.nm_id
from ( select NM.id as nm_id from notification_methods NM
       inner join clients C on C.emails = NM.emails 
             and C.notification_type = NM.notification_type    
) as query
where ????????

可以从clients(信息所在的位置)访问contracts_document_types,但我无法将它们与正确的用户相关联。我在UPDATE FROM 语句中遗漏了一些关于迭代过程的重要内容。

简历:1 个客户有很多contracts_document_types,我有一个基于客户创建的notification_method。我找不到将正确的 notification_method 放在每个客户端(来自该客户端的所有contracts_document_types)的方法。

【问题讨论】:

  • 您能否提供一些客户示例、他们的合同以及简短说明您如何找到此示例数据的通知?
  • 考虑使用临时表使更新语句尽可能简单。我会说在更新中使用子查询不是一个好主意,因为它更难理解而且容易出错......
  • @voytech:有利的一面:一旦你确实理解它,它就会神奇地转变为一个绝妙的想法。
  • 没错。任何人都可以用任何编程语言创建脚本或使用临时表来解决它,这不是一个坏主意,但这种说法似乎很强大,花费的时间很快就会得到回报。

标签: sql postgresql sql-update


【解决方案1】:

我有根据的猜测,它应该像这样工作:

UPDATE contracts_document_types cd
SET    notification_method_id = q.nm_id
FROM  (
   SELECT co.id AS co_id, nm.id AS nm_id
   FROM   contracts co
   JOIN   clients   cl ON cl.id = co.client_id
   JOIN   notification_methods nm USING (emails, notification_type)
   ) q
WHERE  cd.contract_id = q.co_id;

您只是忘记将contracts 表添加为缺失链接。 UPDATE in the manual 的详细信息。

USING 只是语法简写。如果emailsnotification_type 可能模棱两可,请像以前一样明确:

JOIN   notification_methods nm ON nm.emails = cl.emails
                              AND nm.notification_type = cl.notification_type

更简单的是,您甚至不需要子查询:

UPDATE contracts_document_types cd
SET    notification_method_id = nm.id
FROM   contracts co
JOIN   clients   cl ON cl.id = co.client_id
JOIN   notification_methods nm USING (emails, notification_type)
WHERE  cd.contract_id = co.id;

相关:

【讨论】:

  • 按您发布的那样工作,只是更新上的 cd 缩写不起作用,我起飞并运行。谢谢先生。
  • @PedroIvan 太棒了! table alias cd 也应该可以工作 (see documentation) - 除非您使用的是非常旧的 Postgres 版本。该功能是在 Postgres 8.2 中引入的。它只是一个方便的语法快捷方式,完全可选。
猜你喜欢
  • 2021-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-14
  • 2021-04-20
  • 1970-01-01
  • 2015-05-28
相关资源
最近更新 更多