如何创建基于行子集递增的列?

问题描述

我希望有一种方法,每次为该组织创建支持凭单时,即可增加org_ticket_count。在插入之前,可能必须为该组织找到最高的org_ticket_count并递增。另外,当删除support_ticket时,我仍然希望org_ticket_count保持不变。

这是我现在正在做的事情:

CREATE TABLE orgs (
  primary key (org_id),org_id  bigint generated always as identity
);

CREATE TABLE support_tickets (
  primary key (support_ticket_id),support_ticket_id  bigint generated always as identity,org_id             bigint references orgs,org_ticket_count   bigint
);

------------------------

-- Get old ticket count
      SELECT org_ticket_count
        INTO v_old_org_ticket_count
        FROM support_tickets
       WHERE org_id = v_org_id
    ORDER BY support_ticket_id
        DESC
       LIMIT 1;

-- Create new ticket count
          IF v_old_org_ticket_count IS NULL THEN
             -- this is the first issue
             v_new_org_ticket_count := 1;
        ELSE
             v_new_org_ticket_count := v_old_org_ticket_count + 1;
     END IF;

-- Create support ticket
INSERT INTO support_tickets (org_id,org_ticket_count)
     VALUES (v_org_id,v_new_org_ticket_count);

我看到的一个缺陷是,如果您为support_ticket删除了最新的org,它将在下一个org_ticket_count和您的{总数将减少一。

解决方法

不要实现。放下support_tickets.org_ticket_count。这是多余的,并且可能导致不一致。为了方便起见,您可以改用count(*)的窗口版本来创建视图。

CREATE VIEW support_tickets_with_org_ticket_count
AS
SELECT support_ticket_id,org_id,count(*) OVER (PARTITION BY org_id
                      ORDER BY support_ticket_id) org_ticket_count
       FROM support_tickets;

db<>fiddle

,

我建议使用Triggers

  1. 在表ticket_count中再添加一列orgs。因此,新的定义将是:
    CREATE TABLE orgs (
      primary key (org_id),org_id  bigint generated always as identity,ticket_count bigint default 0
    );
  1. 在表after insert的{​​{1}}事件上创建触发器

触发功能

support_tickets

触发

create or replace function trig_fun() 
returns trigger AS
$$
declare
count_ bigint;
begin

select ticket_count into count_ from orgs where org_id=new.org_id;

update support_tickets set org_ticket_count= count_+1 where support_ticket_id=new.support_ticket_id;

update orgs set ticket_count=count_+1 where org_id=new.org_id;


return new;

end;
$$
language plpgsql 

这完全可以满足您的要求。

DEMO