Как создать столбец, который увеличивается на основе подмножества строк?

#postgresql #count

#postgresql #количество

Вопрос:

Я хотел бы иметь 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_ticket , и ваше общее количество уменьшится на единицу.

Ответ №1:

Я бы предложил использовать 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 события таблицы 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 
  

Триггер

 create trigger trig_on_insert 
after insert on 
support_tickets
for each row
execute procedure trig_fun()
  

Это сделает именно то, что вы хотите.

ДЕМОНСТРАЦИЯ

Ответ №2:

Не воплощайте это в жизнь. Удаление 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<> скрипта