我有以下内容:
SELECT
CASE column1
WHEN some_long_calc THEN 10
ELSE some_long_calc + 2*PI
END AS mycalc,
如何“保存”some_long_calc
作为局部变量,所以我不需要运行两次?
我正在使用atan2
,我希望将角度范围保持在0到2pi之间
答案 0 :(得分:3)
首先,我想查询优化器足够智能,可以发现相同的确定性表达式,并且不会计算两次。
如果这不适用,您可以使用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);
输出:
╔═════╦══════════╦════╦════╦════╦════════════╦════════╗
║ id ║ column1 ║ a ║ b ║ c ║ long_calc ║ mycalc ║
╠═════╬══════════╬════╬════╬════╬════════════╬════════╣
║ 1 ║ 6 ║ 1 ║ 2 ║ 3 ║ 6 ║ 10 ║
║ 2 ║ 20 ║ 2 ║ 3 ║ 4 ║ 9 ║ 15.28 ║
╚═════╩══════════╩════╩════╩════╩════════════╩════════╝
您可以使用简单VALUES
或函数调用替换SELECT
:
-- 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)
修改
SELECT id
,sub2.long_calc_rand -- calculated once
,random() AS rand -- calculated every time
FROM tab t
,LATERAL random() AS sub2(long_calc_rand);
输出:
╔═════╦═════════════════════╦════════════════════╗
║ id ║ long_calc_rand ║ rand ║
╠═════╬═════════════════════╬════════════════════╣
║ 1 ║ 0.3426254219375551 ║ 0.8861959744244814 ║
║ 2 ║ 0.3426254219375551 ║ 0.8792812027968466 ║
║ 3 ║ 0.3426254219375551 ║ 0.8123061805963516 ║
╚═════╩═════════════════════╩════════════════════╝