【问题标题】:Update first match row更新第一个匹配行
【发布时间】:2013-07-20 08:58:31
【问题描述】:

我需要根据表 A 聚合更新表 B。 从表 A 聚合到表 B 的关系是 1:M ,但我只想更新 B 中的一个匹配行(它可以是“许多”中的任何行)。

update B set spent = aggregation.spent
from 
(select provider_id,sum(spent) spent from A group by provider_id) aggregation
where B.provider_id = aggregation.provider_id 

添加限制是不合法的。

最后,只有一条来自 B 的匹配记录需要与更新后的花费。

CREATE TABLE A
(
  id bigserial NOT NULL,
  provider_id bigint,
  channel int,
  spent int
 );

CREATE TABLE B
(
  id bigserial NOT NULL,
  provider_id bigint,
  spent int
 );

insert into A values (1,1,1,1);
insert into A values (2,1,2,1);
insert into B values (1,1,0);
insert into B values (2,1,0);

【问题讨论】:

  • 我能问你为什么它可以是“许多”中的任何一行?这听起来很奇怪,这意味着您对更新的记录没有任何控制权,并且没有用于选择要更新的记录的cryteria?我不知道什么样的数据库设计需要这样的东西。
  • 这是从旧表到新表的一次性迁移过程。表 B 用于报告,因此我在提供报告之前进行了汇总,因此我希望该提供者的记录之一将花费迁移。替代方法可以是将旧表中的支出除以新表中的提供者记录。
  • 对不起,我越想理解,就越失败 :) 我只是无法想象你为什么会那样做,似乎这里缺少一些东西并且可能导致数据损坏。我想到了一个 pl/pgsql 函数,但我仍然不明白原因。也许您可以提供一个before and after 查询的示例?

标签: sql postgresql postgresql-9.1


【解决方案1】:

SQL Fiddle

update B set spent = s.spent
from
    (
        select distinct on (provider_id)
            be.id, aggregation.spent
        from
            (
                select provider_id, sum(spent) spent
                from A
                group by provider_id
            ) aggregation
            inner join
            B be using (provider_id)
    ) s    
where B.id = s.id

【讨论】:

  • 我想熟悉不同的...太好了!!!!顺便说一句,有没有办法在更新子句中给表起一个别名?
猜你喜欢
  • 1970-01-01
  • 2021-07-29
  • 1970-01-01
  • 1970-01-01
  • 2012-03-19
  • 2014-06-30
  • 2014-09-16
  • 1970-01-01
  • 2021-03-11
相关资源
最近更新 更多