簡體   English   中英

通過對行進行分組來更新Postgresql中的表

[英]Update table in Postgresql by grouping rows

我想通過基於某些條件將一些行分組(或合並)在一起來更新表。 我目前基本上有此表(我想按“ id_number”和“ date”對“ count”進行分組):

Table: foo
---------------------------------------
|  id_number  |   date      | count  |
---------------------------------------
| 1           |   2001      |    1   |
| 1           |   2001      |    2   |
| 1           |   2002      |    1   |
| 2           |   2001      |    6   |
| 2           |   2003      |    12  |
| 2           |   2003      |    2   |
---------------------------------------

我想得到這個:

Table: foo
 ---------------------------------------
|  id_number  |   date      | count  |
---------------------------------------
| 1           |   2001      |    3   |
| 1           |   2002      |    1   |
| 2           |   2001      |    6   |
| 2           |   2003      |    14  |
---------------------------------------

我知道我可以使用相關信息輕松創建一個新表。 但是,如何在不創建“臨時”表的情況下修改現有表呢? (注意:我沒有反對使用臨時表的信息,我只是想看看是否可以通過這種方式進行操作)

如果要刪除行,則可以添加一個主鍵(用於區分行)並使用兩個句子,對於總和,使用UPDATE ;對於較少的行,使用DELETE

您可以執行以下操作:

create table foo (
  id        integer primary key,
  id_number integer,
  date      integer,
  count     integer
);

insert into foo values
  (1,    1      ,   2001      ,    1   ),
  (2,    1      ,   2001      ,    2   ),
  (3,    1      ,   2002      ,    1   ),
  (4,    2      ,   2001      ,    6   ),
  (5,    2      ,   2003      ,    12  ),
  (6,    2      ,   2003      ,    2   );

select * from foo;

update foo 
  set count = count_sum
  from (
      select id, id_number, date, 
             sum(count) over (partition by id_number, date) as count_sum
        from foo
        ) foo_added
  where foo.id_number = foo_added.id_number 
    and foo.date      = foo_added.date; 

delete from foo 
  using (
      select id, id_number, date, 
             row_number() over (partition by id_number, date order by id) as inner_order
        from foo
        ) foo_ranked
  where foo.id = foo_ranked.id
    and foo_ranked.inner_order <> 1;

select * from foo;

您可以在這里嘗試: http : //rextester.com/PIL12447

僅一次更新

(但有觸發器),您可以在count中設置一個NULL值,並在這種情況下觸發DELETE

create table foo (
  id        integer primary key,
  id_number integer,
  date      integer,
  count     integer
);

create function delete_if_count_is_null() returns trigger 
  language plpgsql as
$BODY$
begin
  if new.count is null then
    delete from foo
      where id = new.id;
  end if;
  return new;
end;
$BODY$;

create trigger delete_if_count_is_null
  after update on foo
  for each row
  execute procedure delete_if_count_is_null();

insert into foo values
  (1,    1      ,   2001      ,    1   ),
  (2,    1      ,   2001      ,    2   ),
  (3,    1      ,   2002      ,    1   ),
  (4,    2      ,   2001      ,    6   ),
  (5,    2      ,   2003      ,    12  ),
  (6,    2      ,   2003      ,    2   );

select * from foo;

update foo 
  set count = case when inner_order = 1 then count_sum else null end
  from (
      select id, id_number, date, 
             sum(count) over (partition by id_number, date) as count_sum,
             row_number() over (partition by id_number, date order by id) as inner_order
        from foo
        ) foo_added
  where foo.id_number = foo_added.id_number 
    and foo.date      = foo_added.date
    and foo.id        = foo_added.id; 

select * from foo;

您可以在以下網址嘗試使用: http : //rextester.com/MWPRG10961

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM