如何根据条件创建一个递增 1 的标志
Posted
技术标签:
【中文标题】如何根据条件创建一个递增 1 的标志【英文标题】:How to create a flag that increments by 1 based on conditions 【发布时间】:2017-05-16 21:53:23 【问题描述】:如何通过查看连续变量的值来创建标志?
例如,在下面的表格(图片)中,
对于 row#1,flag 取值为 1;
从 row#2 开始,它会检查:
If variable1 =lag(variable2)
and variable2=lag(variable1) then flag = lag(flag) else flag increments by 1.
在这种情况下,条件不匹配,因此标志取值为 2。
对于第 3 行: 由于它匹配上述条件标志与2相同
对于row#4:即使匹配上述条件,标志也会变为3,因为前2行(row#2 &row#3)已经匹配
等等..
最终的标志将如下所示:
【问题讨论】:
请阅读meta.***.com/questions/285551/… 和接受的答案 【参考方案1】:请记住,您最好对输入数据进行排序,以使用基于 2 行的聚合来实现“移动标志”。为了这个答案,我添加了一个 row_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;
它是如何工作的?
第一部分是关于提供一列以便稍后在窗口函数中对输入数据进行排序。这将是您当前在表中的任何其他列。在示例中它引入了row_number()
窗口函数来生成这样的数字顺序。
第二部分是我们标记行的地方,假设两个变量之间的交叉等于策略将当前行与前一行进行比较,指标 1 和 0 是否应在此特定行中更改标志。这还不是基于 2 的对聚合。
第三部分介绍了将当前行更改标志指示器与前两行的指示器进行比较,如果后面的 1 行没有更改标志并且后面的 2 行确实更改了它,这意味着我们应该将当前行标记为标志-更改(基于 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 完全正确。我一开始就提到了,因为缺少一些东西:-)以上是关于如何根据条件创建一个递增 1 的标志的主要内容,如果未能解决你的问题,请参考以下文章
Makefile:根据 CC/CXX/FC 值更改编译器标志