2013-07-20 122 views
2

我需要根据表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); 
+0

我能问你为什么*它可以是任何行从 “多” *?这听起来很奇怪,这意味着你对更新的记录没有任何控制,并且没有用于选择更新记录的cryister吗?我无法弄清楚什么样的数据库设计会需要这样的事情。 – Eggplant

+0

这是从旧表格到新表格的一次性迁移过程。表B用于报告,所以我在报告提供之前汇总,所以我希望这个提供者的记录之一将会花费迁移。另一种方法可以是将旧表格中的花费除以新表中的提供者记录。 –

+0

对不起,我试着去了解的越多,我越不能理解:)我无法想象为什么你会这样做,似乎在这里失去了一些东西,并可能导致数据损坏。 pl/pgsql函数是我想到的,但我仍然不明白原因。也许你可以提供一个'查询前后'的例子吗? – Eggplant

回答

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 
+0

我想知道独特的...伟大!顺便说一下,有一种方法可以在update子句中为表提供别名? –

+1

@Avihai是的,只是这样做:'更新B C' –

相关问题