3

I have the following:

SELECT
 CASE column1
  WHEN some_long_calc THEN 10
  ELSE some_long_calc + 2*PI
  END AS mycalc,

How can I "save" some_long_calc as a local variable so I don't need to run it twice?

I am using atan2 and I want to keep my angle range between 0 and 2pi

3
  • waht does AS INT do ? Commented Apr 16, 2016 at 4:54
  • @Eric - PostgreSQL does not have declared variables. Commented Apr 16, 2016 at 4:55
  • stackoverflow.com/questions/3157753/… Commented Apr 16, 2016 at 4:58

1 Answer 1

3

First of all I guess that query optimizer is smart enough to spot the same deterministic expressions and do not calculate it twice.

If this is not applicable you could use LATERAL:

SELECT *,
  CASE column1
     WHEN sub.long_calc THEN 10
     ELSE sub.long_calc + 2 * 3.14
  END AS mycalc
FROM tab t
,LATERAL (VALUES(t.a+t.b+t.c)) AS sub(long_calc);

SqlFiddleDemo

Output:

╔═════╦══════════╦════╦════╦════╦════════════╦════════╗
║ id  ║ column1  ║ a  ║ b  ║ c  ║ long_calc  ║ mycalc ║
╠═════╬══════════╬════╬════╬════╬════════════╬════════╣
║  1  ║       6  ║ 1  ║ 2  ║ 3  ║         6  ║ 10     ║
║  2  ║      20  ║ 2  ║ 3  ║ 4  ║         9  ║ 15.28  ║
╚═════╩══════════╩════╩════╩════╩════════════╩════════╝

You could replace VALUES with simple SELECT or function call:

-- any query
,LATERAL (SELECT t.a+t.b+t.c) AS sub(long_calc)
-- function
,LATERAL random() AS sub(long_calc)
-- function with parameter passing
,LATERAL sin(t.a) AS sub(long_calc)

SqlFiddleDemo2


EDIT:

SELECT id
      ,sub2.long_calc_rand     -- calculated once
      ,random() AS rand        -- calculated every time
FROM tab t
,LATERAL random() AS sub2(long_calc_rand);

SqlFiddleDemo3

Output:

╔═════╦═════════════════════╦════════════════════╗
║ id  ║   long_calc_rand    ║        rand        ║
╠═════╬═════════════════════╬════════════════════╣
║  1  ║ 0.3426254219375551  ║ 0.8861959744244814 ║
║  2  ║ 0.3426254219375551  ║ 0.8792812027968466 ║
║  3  ║ 0.3426254219375551  ║ 0.8123061805963516 ║
╚═════╩═════════════════════╩════════════════════╝
Sign up to request clarification or add additional context in comments.

10 Comments

The calc itself is like 15 lines so it looks ugly :D
@DaynaJuliana That is why LATERAL is nice. You have to place ugly code once :)
this is great ! is the VALUES necessary?
@DaynaJuliana Yes, you could use function and pass arguments from main query too :)
You could place it after last JOIN. If you have multiple complex joins "combine" them in one using subquery/CTE
|

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.