4

Say I have a table X, and X has fields X1, X2 and X3.

I want a solution that whenever I insert values for X1 and X2, X3 is set automatically to the sum of X1 and X2 with a trigger.

This is something very simple to do in mysql, but after a while on google I cant find a good example of this for postgres, just some info about For each row triggers, but again no examples.

1
  • Show us sample data and expected result. Please read How-to-Ask And here is a great place to START to learn how improve your question quality and get better answers. Commented May 10, 2016 at 14:54

2 Answers 2

7

Create the trigger function:

create or replace function update_calc_column()
  returns trigger
as
$$
begin
  new.x3 := new.x1 + new.x2;
  return new;
end;
$$
language plpgsql;

Create the trigger:

create trigger calc_trigger 
   before insert or update on X
   for each row
   execute procedure update_calc_column();

SQLFiddle: http://sqlfiddle.com/#!15/7ed21/1

The above is essentially a stripped down version of the example in the manual
http://www.postgresql.org/docs/current/static/plpgsql-trigger.html#PLPGSQL-TRIGGER-EXAMPLE


However, storing derived data like that is usually not a good idea. You should simply create a view that returns a column X3 which is defined as X1 + X2 - a lot less code to maintain and just as efficient (actually it's more efficient because you get rid of the trigger overhead).


Another (more exotic) option is to use Postgres' object oriented extension and create a virtual column:

create or replace function x3(data X) --<< yes, the type of the parameter is the name of the table 
   returns integer
as
$$
   select data.x1 + data.x2;
$$
language sql;

You can then use:

select x.*, x.x3
from x;

SQLFiddle: http://sqlfiddle.com/#!15/53acf/1

This however has the disadvantage that you need to explicitely select the x3 column. It will not show up when using x.*

Sign up to request clarification or add additional context in comments.

2 Comments

thanks, actually this is for a read heavy application, where reads are an order of magnitude higher than writes, and I will have billions of rows and x will have over a 100 fields, it is for this reason that I want to store sums and averages or some different common use fields because it will make the production of reports faster, it definitely did in mysql, but if theres something i missed about postgres please let me know.
@user3306481: if you need aggregates and other calculations you should rather look into materialized views.
1

If all you need is just to calculate the X3 value as a sum of X1 and X2 you can use

ALTER TABLE yourTable
ADD COLUMN x3 BIGINT GENERATED ALWAYS AS (x1 + x2) STORED;

A stored generated column is computed when it is written (inserted or updated) and occupies storage as if it were a normal column. So from the performance point of view it is also performant (no calculations are done on SELECT).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.