我看过很多关于这个话题的帖子,但我找不到完全相同的.

我想用一个专栏来表达自己的观点.在下面的例子中:

  • 值1+2是在整个视图中持续的静态值.
  • 值3有更新的数据,所以当值3中有数据时,我希望它执行值3+(值1-值2).
  • 当值3没有数据时,使用它的前一个值进行计算.
Index Value1 Value2 Value3 Calculation
1 0.5 0.25 1 1.25
2 0.5 0.25 1.5
3 0.5 0.25 1.75

这可能吗?到目前为止,我已经使用滞后或递归CTE计算了index=2的行,但似乎无法解决如何使其继续计算.

推荐答案

通过略作扩展的示例数据,显示了一个新的值3,这是一个先例:

WITH data(Index, Value1, Value2, Value3) AS (
    SELECT * FROM VALUES   
    (1, 0.5, 0.25,  1),
    (2, 0.5, 0.25,  null),
    (3, 0.5, 0.25,  null),
    (4, 0.5, 0.25,  10),
    (5, 0.5, 0.25,  null),
    (6, 0.5, 0.25,  null),
    (7, 0.5, 0.25,  null)
)
select d.*
    ,iff(d.value3 is not null, d.index, null) as idx_k
    ,lag(d.value3) ignore nulls over(order by d.index) as l_value3
    ,lag(idx_k) ignore nulls over(order by d.index) as l_idx_k
    ,d.index - iff(idx_k is not null, idx_k, l_idx_k)+1 as r_d
    ,iff(d.value3 is not null, d.value3, l_value3) + r_d*(d.value1-d.value2) as calc
from data as d
order by 1;

给予:

INDEX VALUE1 VALUE2 VALUE3 IDX_K L_VALUE3 L_IDX_K R_D CALC
1 0.5 0.25 1 1 1 1.25
2 0.5 0.25 1 1 2 1.5
3 0.5 0.25 1 1 3 1.75
4 0.5 0.25 10 4 1 1 1 10.25
5 0.5 0.25 10 4 2 10.5
6 0.5 0.25 10 4 3 10.75
7 0.5 0.25 10 4 4 11

可以被粉碎成:

select d.*
    ,iff(d.value3 is not null, d.value3, lag(d.value3) ignore nulls over(order by d.index)) + (d.index - iff(d.value3 is not null, iff(d.value3 is not null, d.index, null), lag(iff(d.value3 is not null, d.index, null)) ignore nulls over(order by d.index))+1)*(d.value1-d.value2) as calc
from data as d

如果你真的想,但我更倾向于将其包装在子 Select 中,以便更好地呈现:

select index, value1, value2, value3, calc 
from (
    select d.*
        ,iff(d.value3 is not null, d.index, null) as idx_k
        ,lag(d.value3) ignore nulls over(order by d.index) as l_value3
        ,lag(idx_k) ignore nulls over(order by d.index) as l_idx_k
        ,d.index - iff(idx_k is not null, idx_k, l_idx_k)+1 as r_d
        ,iff(d.value3 is not null, d.value3, l_value3) + r_d*(d.value1-d.value2) as calc
    from data as d
)
order by 1

递归CTE:

WITH recursive r_cte as (
    select index, value1, value2, value3, value3 as calc
    from data 
    where index = 1
    
    union all
    
    select d.index, d.value1, d.value2, d.value3, iff(d.value3 is null, r.calc, d.value3) + d.value1 - d.value2 as calc
    from r_cte as r
    join data d on r.index + 1 = d.index
)
select * from r_cte

Sql相关问答推荐

基于多个字段删除Access中的重复记录,同时保留最低优先级

Postgres:对包含数字的字符串列表进行排序

防止ActiveRecord迁移在db/structure.sql中进行巨大更改

过go 四周未填充的数据,即W50,51,52-SQL

当我返回 sql 列时,有没有办法只反转数字? ( hebrew )

在 PostgreSQL 中,如何让多个判断约束引用相同的值数组?

如何查询自引用 comments 表以查找带有回复的 comments ,并按最新回复排序?

SQL Select 字母范围没有给我任何东西

如何从postgresql中的项目映射(关联数组)设置值?

在where语句中使用CTE非常缓慢

标量子查询中的窗口函数不起作用

将表格和字符串连接以 for each 记录生成订单项目

如何在插入时将字符串'03-January-2023'转换为日期时间

为重复的项目编号显示正在处理

PostgreSQL - 从同一张表中获取值

忽略与给定列匹配的行的 LAG 函数

具有关联统计信息 N+1 的 Rails 6 索引资源?

Oracle SQL 查询自行运行,但在包装到select count(*) from ()时失败

SQL:有没有办法根据另一列的数据细节过滤和形成另一列?

提取字符串中的最后一个数字