Postgresql 如何根据条件创建增量为1的标志
如何通过查看连续变量的值来创建标志 例如,在下表(图)中 对于行#1,flag取值1 对于第2行之后的内容,它将检查:Postgresql 如何根据条件创建增量为1的标志,postgresql,aggregate-functions,window-functions,Postgresql,Aggregate Functions,Window Functions,如何通过查看连续变量的值来创建标志 例如,在下表(图)中 对于行#1,flag取值1 对于第2行之后的内容,它将检查: If variable1 =lag(variable2) and variable2=lag(variable1) then flag = lag(flag) else flag increments by 1. 在这种情况下,条件不匹配,因此标志值为2 对于第3排的: 因为它与上述条件匹配,所以标志与2相同 对于第4行:即使符合上述条件,标志也会更改为3,因为前2
If variable1 =lag(variable2)
and variable2=lag(variable1) then flag = lag(flag) else flag increments by 1.
在这种情况下,条件不匹配,因此标志值为2
对于第3排的:
因为它与上述条件匹配,所以标志与2相同
对于第4行:即使符合上述条件,标志也会更改为3,因为前2行(第2行和第3行)已经匹配
等等
最终的标志将如下所示:
请记住,最好对输入数据进行排序,以实现基于两行聚合的“移动标志”。为了回答这个问题,我添加了一个
row\u number()
函数来生成给定样本数据的顺序
测试数据
create table flagtest( var1 text, var2 text);
insert into flagtest(var1,var2) values
('T','Z'),('B','A'),('A','B'),('B','A'),('A','B'),('A','B'),
('A','B'),('B','A'),('C','D'),('E','F'),('F','E'),('M','N');
代码
-- fourth part
select var1, var2, sum(change_flag_2_based) over (order by ordcol) as flag
from( -- third part
select *,
case when
lag(change_flag) over (order by ordcol) = 0
and lag(change_flag, 2) over (order by ordcol) = 1
then 1 else change_flag
end as change_flag_2_based
from ( -- second part
select
var1, var2, ordcol,
case when
var1 = lag(var2) over (order by ordcol) and
var2 = lag(var1) over (order by ordcol)
then 0 else 1
end as change_flag
from ( -- first part
select var1, var2, row_number() over () as ordcol
from flagtest
) ordered_data
) prep_aggr_all
) prep_aggr_two_rows_based;
它是如何工作的?
- 第一部分是关于提供一列,以便稍后在窗口函数中对输入数据进行排序。这将是您当前表中的任何其他列。在本例中,它引入了
window函数来生成这样的数字顺序row\u number()
- 第二部分是我们标记行的地方,假设两个变量之间的交叉策略等于当前行与前一行的比较,指标1和0指示标志是否应在该特定行中更改。这不是一个基于2的对聚合(目前)
- 第三部分介绍了将当前行更改标志指示器与前两行的指示器进行比较,如果后面一行未更改标志,后面两行更改标志,则意味着我们应将当前行标记为更改标志(基于两行的标志)
- 第四部分是移动求和,它通过对这些组求和来生成最终标志
var1 | var2 | flag
------+------+------
T | Z | 1
B | A | 2
A | B | 2
B | A | 3
A | B | 3
A | B | 4
A | B | 5
B | A | 5
C | D | 6
E | F | 7
F | E | 7
M | N | 8
请阅读并接受答案当然表格行的顺序不是固定的,但这是问题的问题,而不是答案。@LaurenzAlbe。我一开始就提到了,因为缺少了一些东西:-)