2016-02-15 5 views
0

Текущие данныеДата Pick & Сравнение строк

100022946 02/11/2014 02/01/2015 Lapsed 
100022946 02/01/2015 05/01/2015 Active 
100022946 05/01/2015 11/01/2015 Active 
100022946 29/06/2000 05/01/2015 Lapsed 
100022946 04/07/2014 05/07/2014 Lapsed 
100022946 05/07/2014 26/07/2014 Lapsed 
100022946 26/07/2014 31/07/2014 Lapsed 
100022946 31/07/2014 17/08/2014 Lapsed 
100022946 17/08/2014 31/08/2014 Long 
100022946 31/08/2014 07/09/2014 Active 
100022946 07/09/2014 07/10/2014 Lapsing 

Ожидаемые данные * Пожалуйста, проверьте даты начала и для изменения активности для производства логика/*

100022946 02/11/2014 02/11/2014 Lapsed 
100022946 02/01/2015 11/01/2015 Active 
100022946 11/01/2015 17/08/2015 Lapsed 
100022946 17/08/2015 31/08/2014 Long 
100022946 31/08/2014 07/09/2014 Active 
100022946 07/09/2014 07/10/2014 Lapsing 
+0

что такое изменение в действии column? как он рассчитывается? – Dawn

ответ

0
shA, here is the final answer 

--Sample table creation Script 
create table sesht(CUSTID int,fromdate date,activity char(1)); 
--Sample data 
insert into sesht values (1,'01-JAN-2015' ,'A') ; 
insert into sesht values (1,'05-JAN-2015' ,'A') ; 
insert into sesht values (1,'10-JAN-2015' ,'B') ; 
insert into sesht values (1,'12-JAN-2015' ,'B') ; 
insert into sesht values (1,'15-JAN-2015' ,'B') ; 
insert into sesht values (1,'16-JAN-2015' ,'A') ; 
insert into sesht values (1,'20-JAN-2015' ,'C') ; 
insert into sesht values (1,'22-JAN-2015' ,'C') ; 
insert into sesht values (1,'24-JAN-2015' ,'C') ; 

----Base table - work out next record and see if the data is chagnged and rownumber is assigned to every record 

drop table seshtt ; 


create table seshtt as 
Select custid,fromdate,COALESCE(activity,'') Activity 
,CASE 
WHEN COALESCE(activity,'') <> COALESCE(LEAD(activity) OVER (PARTITION BY CUSTID ORDER BY rn),'') THEN 
LEAD(FromDate) OVER (PARTITION BY CUSTID ORDER BY FromDate) 
END AS prevFromDate 
,rn 
from 
(
Select custid,fromdate, activity, ROW_NUMBER() OVER (PARTITION BY CUSTID ORDER BY FromDate) rn from sesht 
) 
; 
Select aa.custid,aa.fromdate,(NULL) TODATE,activity,aa.rn from seshtt aa 
join 
(
select custid,max(rn)+1 rn from seshttt 
group by custid 
) bb 
on aa.custid=bb.custid 
and aa.rn=bb.rn; 



select * from seshttt ; 

----Build main records (First & last records are not sorted) 

create table seshttt as 
SELECT custid, COALESCE(LAG(prevFromDate) OVER (PARTITION BY CUSTID ORDER BY fromdate), FromDate) FromDate, prevFromDate ToDate, Activity,rn 
FROM seshtt 
WHERE prevFromDate IS NOT NULL AND FromDate IS NOT NULL; 

----Last record is now sorted & it becomes main table where first record will need to be updated 

create table seshtttt as 
Select * from seshttt 
UNION ALL 
Select aa.custid,aa.fromdate,(NULL) TODATE,activity,aa.rn from seshtt aa 
join 
(
select custid,max(rn)+1 rn from seshttt 
group by custid 
) bb 
on aa.custid=bb.custid 
and aa.rn=bb.rn; 

select * from seshtttt; 
---First record is sorted from both tables and rowid is used to merge the dataset; 

create table seshtttttt as 
Select src.*,bb.fromdate srcdate from 
(

Select aa.custid,aa.fromdate,aa.rowid rwid from seshtttt aa join 
(
Select custid,min(rn) rn from seshtttt group by custid 
) bb 
on aa.custid=bb.custid and aa.rn=bb.rn 
) src 
join 
(
Select custid,fromdate from seshtt where rn=1 
) bb 
on src.custid=bb.custid; 

select * from seshtttttt ; 

---Merge runs here 

merge into seshtttt tgt 
using seshtttttt src 
on 
(tgt.rowid=src.rwid 
and tgt.custid=src.custid) 
when 
matched then 
update set tgt.fromdate=src.srcdate; 

commit; 


select * from seshtttt ; 

1. List item 
0

Я думаю, что на первом вам нужно индекс, чтобы упорядочить ваши данные над ним, используя что-то вроде ROW_NUMBER() OVER (ORDER BY (SELECT null)), затем найдите измененный Activity с возвратом следующего FromDate для этой записи, тогда вам нужно вернуть прежнее FromDate после фильтрации неизмененных записей ; Но вы будете иметь некоторые проблемы с первой строки, которые я обрабатывать его с UNION, как это:

WITH t AS (
SELECT *, 
    ROW_NUMBER() OVER (ORDER BY (SELECT null)) rn 
FROM yourTable 
), nt AS (
SELECT *, 
    CASE 
     WHEN Activity <> ISNULL(LEAD(Activity) OVER (PARTITION BY ID ORDER BY rn), '') THEN 
      ISNULL(LEAD(FromDate) OVER (PARTITION BY ID ORDER BY rn), 0) 
    END AS prevFromDate 
FROM t 
UNION ALL 
SELECT ID,null,null,null, 1, FromDate 
FROM t 
WHERE rn = 1 
) 
SELECT ID, ISNULL(LAG(prevFromDate) OVER (PARTITION BY ID ORDER BY rn), FromDate) FromDate, ToDate, Activity 
FROM nt 
WHERE prevFromDate IS NOT NULL AND FromDate IS NOT NULL; 

Я не проверить его еще.

+0

Спасибо shA, запрос работал 90%, и мы работаем над остальными, чтобы получить окончательный результат, ваш намек на это очень заметен, много спасибо – nkalis