2013-07-20 81 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' –

相關問題