Есть ли способ передать столбец с объединенным значением из двух других столбцов, динамически увеличивая значение int в третьем столбце?

#sql #postgresql

#sql #postgresql

Вопрос:

Я хочу создать триггерную функцию для отправки столбца со значением, сгенерированным из объединения двух других столбцов с заранее заданными значениями. Если значение уже существует, я бы увеличил третий столбец соответственно объединенному значению.

ПРИМЕР:

 column1 -> 'aaa' 
column2 -> 'bbb' 

concatenated value -> 'aaabbb'

column1 -> 'xxx'
column2 -> 'yyy'

concatenated value -> 'xxxyyy'`
  

Если уже есть строки со значением ‘aaabbb’, то третий столбец будет увеличен как:

 1 | aaabbb
2 | aaabbb
3 | aaabbb
1 | xxxyyy
2 | xxxyyy
  

Комментарии:

1. Итак, вы хотите вставить новую строку с объединенным значением и количеством значений, которые ему соответствуют?

2. Точно, ваше описание было идеальным.

3. Итак, после вставки column1 было бы 'aaabbb' , column2 было бы NULL и column3 количество совпадающих значений? Или оба column1 и column2 являются объединенным значением?

4. Объединенное значение из column1 и column2 будет вставлено в другой столбец и будет содержать столбец для подсчета объединенных значений. В итоге будет четыре столбца.

5. Как эмпирическое правило для реляционной базы данных: не храните данные, которые могут быть легко получены из существующих значений. Создайте представление, которое возвращает эту информацию, и забудьте о повторном сохранении данных.

Ответ №1:

Не уверен, хотите ли вы сохранить объединенное значение. Это не сохраняет его, но вы, конечно, можете сохранить объединенное значение в new.concatenated_column :

 create function f_test ()
returns trigger
language plpgsql
as $$
begin
    new.column3 := (
        select coalesce(max(t.column3)   1, 1)
        from test as t
        where t.column1 || t.column2 = new.column1 || new.column2
    );

    return new;
end;    
$$

create trigger tr_test
before insert
on test
for each row execute procedure f_test();
  

db<>fiddle demo

Ответ №2:

Вы можете попробовать использовать этот код, его работа заключается только в insert. Но вы также можете дублировать триггер и изменять его на update.

 create table test ( column1 varchar, column2 varchar, column3 varchar);

CREATE TRIGGER t_before_test
  BEFORE insert 
  ON test

FOR EACH ROW 
    EXECUTE PROCEDURE fnt_test();


CREATE OR REPLACE FUNCTION fnt_test()
  RETURNS trigger LANGUAGE plpgsql AS
$BODY$
declare
    v_count int := 0;
BEGIN
    select 1 into v_count from test where column1 = NEW.column1 and column2 = NEW.column2;
    if ( NEW.column1 is not null and NEW.column2 is not null and v_count > 0) then
        NEW.column3 := NEW.column1 || NEW.column2;
    end if;

 RETURN NEW;
END;
$BODY$;

insert into test ( column1, column2 ) values ( '1', '2');

select * from test;