简体   繁体   中英

Date Pick & String comparison

Current Data

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

Expected Data * Please check the from and to dates for activity change to produce the logic /*

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

I think at first you need an index to order your data over it by using something like ROW_NUMBER() OVER (ORDER BY (SELECT null)) then finding changed Activity with returning next FromDate for that record then you need to return that previous FromDate after filtering unchanged records; But you will have some problems with first row that I handle it with a UNION like this:

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;

I don't test it yet.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM