В настоящее время у меня есть таблица, которая выглядит так

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

Я хочу отслеживать, было ли время, когда X != C когда-либо за предыдущие 12 месяцев, и отмечать это

|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
I.m.rich 8 Май 2018 в 23:03

1 ответ

Лучший ответ

Я бы не стал использовать 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);
3
Gordon Linoff 8 Май 2018 в 20:15