根据当前行和上一行中的值计算当前行 col 值
compute current row col value based on values in current and previous row
有table即。 table1
其中有 Time
、Col1
和 Col2
字段。我想要做的是创建一个新的 table table2
,其中包括基于 Col1
和 Col2
值计算的每一行的 Col3
值table1
的 SQL 中的当前行和上一行。 table2
要求的格式如下
table2
Time Col1 Col2 Col3
09:37.43.755 1 0 0.0 #=> col3 row1 start value = 0
09:37.44.255 5 2 0.3333 #=> (row2.col2-row1.col2)/((row2.col2-row1.col2)+(row2.col1-row1.col1)) => (2-0)/((2-0) + (5-1)) => 2/6 = 0.3333
09:37.44.755 10 2 0.0 #=> (row3.col2-row2.col2)/((row3.col2-row2.col2)+(row3.col1-row2.col1)) => (2-2)/((2-2) + (10-5)) => 0/5 = 0.0
09:37.45.255 10 2 0.0 # similar to row2,3 but a div by 0 case => (2-2)/( (2-2) + (10-10)) = 0/0 => this should be mapped to 0 if the numerator is 0.
在这里最适合您的工具可能是 LAG 窗口聚合函数。不过,可能有几种不同的方法可以做到这一点。这是一个使用 LAG 和子查询的示例。窗口聚合函数非常有用,所以我要说的是去了解它们!
select * from table1 order by time, col1;
TIME | COL1 | COL2
--------------+------+------
09:37:43.755 | 1 | 0
09:37:44.255 | 5 | 2
09:37:44.755 | 10 | 2
09:37:45.255 | 10 | 2
(4 rows)
select time, col1, col2,
coalesce ( case
when (
col2-lag_col2
)
+ (col1-lag_col1) = 0 then 0
else ((col2-lag_col2)*1.0/((col2-lag_col2)+(col1-lag_col1)))::NUMERIC(5,4)
END , 0) col3
from (
select time, col1, col2,
lag(col1) over (order by time, col1) lag_col1,
lag(col2) over (order by time, col1) lag_col2
from table1
)
foo;
TIME | COL1 | COL2 | COL3
--------------+------+------+--------
09:37:43.755 | 1 | 0 | 0.0000
09:37:44.255 | 5 | 2 | 0.3333
09:37:44.755 | 10 | 2 | 0.0000
09:37:45.255 | 10 | 2 | 0.0000
(4 rows)
有table即。 table1
其中有 Time
、Col1
和 Col2
字段。我想要做的是创建一个新的 table table2
,其中包括基于 Col1
和 Col2
值计算的每一行的 Col3
值table1
的 SQL 中的当前行和上一行。 table2
要求的格式如下
table2
Time Col1 Col2 Col3
09:37.43.755 1 0 0.0 #=> col3 row1 start value = 0
09:37.44.255 5 2 0.3333 #=> (row2.col2-row1.col2)/((row2.col2-row1.col2)+(row2.col1-row1.col1)) => (2-0)/((2-0) + (5-1)) => 2/6 = 0.3333
09:37.44.755 10 2 0.0 #=> (row3.col2-row2.col2)/((row3.col2-row2.col2)+(row3.col1-row2.col1)) => (2-2)/((2-2) + (10-5)) => 0/5 = 0.0
09:37.45.255 10 2 0.0 # similar to row2,3 but a div by 0 case => (2-2)/( (2-2) + (10-10)) = 0/0 => this should be mapped to 0 if the numerator is 0.
在这里最适合您的工具可能是 LAG 窗口聚合函数。不过,可能有几种不同的方法可以做到这一点。这是一个使用 LAG 和子查询的示例。窗口聚合函数非常有用,所以我要说的是去了解它们!
select * from table1 order by time, col1;
TIME | COL1 | COL2
--------------+------+------
09:37:43.755 | 1 | 0
09:37:44.255 | 5 | 2
09:37:44.755 | 10 | 2
09:37:45.255 | 10 | 2
(4 rows)
select time, col1, col2,
coalesce ( case
when (
col2-lag_col2
)
+ (col1-lag_col1) = 0 then 0
else ((col2-lag_col2)*1.0/((col2-lag_col2)+(col1-lag_col1)))::NUMERIC(5,4)
END , 0) col3
from (
select time, col1, col2,
lag(col1) over (order by time, col1) lag_col1,
lag(col2) over (order by time, col1) lag_col2
from table1
)
foo;
TIME | COL1 | COL2 | COL3
--------------+------+------+--------
09:37:43.755 | 1 | 0 | 0.0000
09:37:44.255 | 5 | 2 | 0.3333
09:37:44.755 | 10 | 2 | 0.0000
09:37:45.255 | 10 | 2 | 0.0000
(4 rows)