计算表的最佳方法是什么,其中许多列是从同一个表中的其他列计算的,并且公式以复杂的方式相互构建。
如果您不关心性能,则只需使用自己的更新语句计算每个列:
update x set b1 = a1 + a2;
update x set b2 = a3 * b1;
update x set b3 = a4 * b2;
...
或者,如果手动展开公式,则可以在单个更新中执行所有操作:
update x set
b1 = a1 + a2,
b2 = a3 * (a1 + a2),
b3 = a4 * (a3 * (a1 + a2));
这里的问题是这些公式可能变得庞大且难以更改和调试。
在Postgres(或者甚至是一般的SQL)中是否有某种方式可以在这些情况下同时具有性能和可维护性?
这是我希望我能做的事情:
update x set
b1 = _b1,
b2 = _b2,
b3 = _b3
with
_b1 = a1 + a2,
_b2 = a3 * _b1,
_b3 = a4 * _b2;
我有一个工作解决方案,其中公式在具有多个返回值的函数中定义,但这在其他方面相当不灵活,所以我正在寻找替代方案。
您可以在最近的PostgreSQL版本中使用以下内容:
UPDATE atable
SET (col1, col2, col3) =
SELECT expr1, expr2, expr3
FROM ...
如果需要在查询中重用计算表达式,可以使用WITH
:
WITH t1(x1) AS (
SELECT /* complicated */
), t2(x2) AS (
SELECT /* complicated using t1 */
) ...
SELECT /* final results */
我不确定这是否会使代码对您更具可读性,但它避免使用函数并且符合标准(我认为,没有检查)。
我想出了一些接近我想要的东西:
update x set (b1, b2, b3) = ((
select b1, b2, b3
from (select b1, b2, a4 * b2 as b3
from (select b1, a3 * b1 as b2
from (select a1 + a2 as b1
) as _) as _) as _
));
它仍然比我想要的更冗长,但基本上实现了不使用函数而不必扩展公式的目标。