如何在SQL中滞后多个月

时间:2018-05-08 20:03:33

标签: sql sql-server

我目前有一个看起来像这样的表

|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个。

有什么建议吗?

1 个答案:

答案 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);