我目前有一个看起来像这样的表
|DataDt|ID|X|Y|
|1.1.10|1 |C|7|
|2.1.10|1 |C|5|
|3.1.10|1 |C|4|
|4.1.10|1 |C|8|
|5.1.10|1 |C|1|
|6.1.10|1 |3|2|
|7.1.10|1 |6|7|
|8.1.10|1 |C|7|
|1.1.10|2 |C|7|
|2.1.10|2 |C|7|
|3.1.10|2 |3|7|
|4.1.10|2 |C|7|
我想跟踪过去12个月中任何时间点X != C
是否有时间并标记
|DataDt|ID|X |Y|Flag
|1.1.10|1 |C |7|0
|2.1.10|1 |C |5|0
|3.1.10|1 |C |4|0
|4.1.10|1 |C |8|0
|5.1.10|1 |C |1|0
|6.1.10|1 |3 |2|0
|7.1.10|1 |6 |7|1
|8.1.10|1 |C |7|1
|1.1.10|2 |C |7|0
|2.1.10|2 |C |7|0
|3.1.10|2 |3 |7|0
|4.1.10|2 |C |7|1
通常我使用以下代码来延迟上个月:
;select ID, datadt, X, flag into X_Table from Data
(
Select loan_num, datadt, X, flag,
Lag(X) Over (Partition By ID Order By datadt Asc) As Prev
From X_Table
)
Update X_Table
Set flag = 1
where prev != 'C'
然而,这只能工作一个月而不是12个。
有什么建议吗?
答案 0 :(得分:3)
我不会使用lag()
,而是exists
:
update X_Table
set flag = 1
where exists (select 1
from X_table x2
where x2.id = X_table.id and
x2.x <> 'C' and
x2.datadt > x.datadt - interval '12 month' and
x.datadt <= x.datadt
);
请注意,这使用ANSI标准语法进行日期算术,因为您尚未指定数据库。
您可以使用窗口功能,但lag()
不合适。假设您每个月都有一行(没有间隙):
with toupdate as (
select x.*,
sum(case when x <> 'C' then 1 else 0 end) over (partition by id order by datadt rows between 11 preceding and current row) as num_notc
from x_table x
)
update toupdate
set flag = (case when num_notc > 0 then 1 else 0 end);