I have a pretty complex SQL statement in my PostgreSQL database which I use as a basis in several views. But in this statement, a sum aggregate function is called multiple times. I'm now seeking to optimize these views by getting rid of summarizing these values multiple times by using a variable.
I know I can use @myvalue = 1, but this is in pgScript and it can't be used in a view as it is pgScript.
I have read about abusing the config settings to store a variable in, but I don't know how this plays with views and I'm not really fond of such hacks.
The part from the SQL I want to store in a variable is sum(v."Surface")::double precision which is repeated multiple times.
If there are any other suggestions for optimizing this SQL I'm all for it.
CREATE OR REPLACE VIEW mydb."MyTable" AS
SELECT p."Id",
v."FunctionInt",
v."TypeInt",
sum(v."Surface") AS "SurfaceTotaal",
round((sum(v."Surface"::double precision * v."Average") / sum(v."Surface")::double precision)::numeric, 1) AS "Average",
round((sum(v."Surface"::double precision * v."E") / sum(v."Surface")::double precision)::numeric, 1) AS "E",
round((sum(v."Surface"::double precision * v."E1") / sum(v."Surface")::double precision)::numeric, 1) AS "E1",
round((sum(v."Surface"::double precision * v."E2") / sum(v."Surface")::double precision)::numeric, 1) AS "E2",
round((sum(v."Surface"::double precision * v."E3") / sum(v."Surface")::double precision)::numeric, 1) AS "E3",
round((sum(v."Surface"::double precision * v."M") / sum(v."Surface")::double precision)::numeric, 1) AS "M",
round((sum(v."Surface"::double precision * v."M1") / sum(v."Surface")::double precision)::numeric, 1) AS "M1",
round((sum(v."Surface"::double precision * v."M2") / sum(v."Surface")::double precision)::numeric, 1) AS "M2",
round((sum(v."Surface"::double precision * v."M3") / sum(v."Surface")::double precision)::numeric, 1) AS "M3",
round((sum(v."Surface"::double precision * v."G") / sum(v."Surface")::double precision)::numeric, 1) AS "G",
round((sum(v."Surface"::double precision * v."G1") / sum(v."Surface")::double precision)::numeric, 1) AS "G1",
round((sum(v."Surface"::double precision * v."G2") / sum(v."Surface")::double precision)::numeric, 1) AS "G2",
round((sum(v."Surface"::double precision * v."G3") / sum(v."Surface")::double precision)::numeric, 1) AS "G3",
round((sum(v."Surface"::double precision * v."G4") / sum(v."Surface")::double precision)::numeric, 1) AS "G4"
FROM mydb."PTable" p,
LATERAL (
SELECT
v."Id",
v."Surface",
v."FunctionInt",
v."TypeInt",
r."YearGroupInt",
r."Average",
r."En" AS "E",
r."En1" AS "E1",
r."En2" AS "E2",
r."En3" AS "E3",
r."Mi" AS "M",
r."Mi1" AS "M1",
r."Mi2" AS "M2",
r."Mi3" AS "M3",
r."Gz" AS "G",
r."Gz1" AS "G1",
r."Gz2" AS "G2",
r."Gz3" AS "G3",
r."Gz4" AS "G4"
FROM mydb."VTable" v
JOIN mydb."RTable" r ON
v."FunctionInt" = r."FunctionInt"
AND v."TypeInt" = r."TypeInt"
AND v."YearGroupInt" = r."YearGroupInt"
WHERE v."PId" = p."Id") v
GROUP BY p."Id", v."FunctionInt", v."TypeInt";
create function(var) returns table?..sum(v."Surface")appears 1000 times in your query, the optimizer is smart enought and knows that this is the same value, and calculates it only once, not 1000 times.