Author |
Topic |
jhoop2002
Starting Member
1 Post |
Posted - 2014-10-09 : 15:02:37
|
I have a need to determine whether a client's policy was active or not on a given date. Unfortunately, I'm not sure how to do this.Here is my data:CustNo, CustomerName, PolEffDate, PolExpDate, LineOfBus, EffDate, Description274, Smart, Susan, 2/6/14 12:00:00 AM, 2/6/15 12:00:00 AM, 11/15/14 12:00:00 AM, Reinstatement274, Smart, Susan, 2/6/14 12:00:00 AM, 2/6/15 12:00:00 AM, 10/31/14 12:00:00 AM, Cancellation274, Smart, Susan, 2/6/14 12:00:00 AM, 2/6/15 12:00:00 AM, 8/8/14 12:00:02 AM, Reinstatement274, Smart, Susan, 2/6/14 12:00:00 AM, 2/6/15 12:00:00 AM, 8/8/14 12:00:01 AM, Cancellation274, Smart, Susan, 2/6/14 12:00:00 AM, 2/6/15 12:00:00 AM, 2/6/14 12:00:00 AM, NewHere is the break down on when this policy is active.from 02/06/12 -> 08/08/14 == Activefrom 08/08/14 -> 10/31/14 == Activefrom 10/31/14 -> 11/15/14 == Inactivefrom 11/15/14 -> 02/06/15 == ActiveIf you notice the time increments on 08/08/14, that is to signify the order of the transaction - not the actual effective time. Effetive time is always 12:00 am.Any help would be appreciated. |
|
Milira
Starting Member
1 Post |
Posted - 2014-10-09 : 15:47:40
|
select '274' as CustNo, 'Smart, Susan' as CustomerName, '2/6/14 12:00:00 AM' as PolEffDate, '2/6/15 12:00:00 AM' as PolExpDate, '11/15/14 12:00:00 AM' as EffDate, 'Reinstatement' as Descriptioninto #temp insert #tempselect '274', 'Smart, Susan', '2/6/14 12:00:00 AM', '2/6/15 12:00:00 AM', '10/31/14 12:00:00 AM', 'Cancellation'insert #tempselect '274', 'Smart, Susan', '2/6/14 12:00:00 AM', '2/6/15 12:00:00 AM', '8/8/14 12:00:02 AM', 'Reinstatement'insert #tempselect '274', 'Smart, Susan', '2/6/14 12:00:00 AM', '2/6/15 12:00:00 AM', '8/8/14 12:00:01 AM', 'Cancellation'insert #tempselect '274', 'Smart, Susan', '2/6/14 12:00:00 AM', '2/6/15 12:00:00 AM', '2/6/14 12:00:00 AM', 'New'select case t.description when 'New' then 'Active' when 'Reinstatement' then 'Active' when 'Cancellation' then 'Inactive' end, convert(date,t.EffDate) as PeriodStart, convert(date,isnull(t1.effdate,t.PolExpDate)) as PeriodEndfrom #temp t inner join ( select CustNo, max(convert(datetime, EffDate)) as EffDate,CustomerName,PolEffDate,PolExpDate from #temp group by CustNo, convert(date, EffDate),CustomerName,PolEffDate,PolExpDate) a on a.CustNo = t.CustNo and convert(datetime, t.EffDate) = a.EffDate left join #temp t1 on t1.CustNo = t.CustNo and t1.EffDate = (select MIN(convert(datetime,effDate)) from #temp where convert(datetime, EffDate) > convert(datetime, t.EffDate)) order by convert(datetime, t.EffDate) |
|
|
lazerath
Constraint Violating Yak Guru
343 Posts |
Posted - 2014-10-24 : 16:15:12
|
This solution works with multiple customers, handles duplicates, is a lot faster (esp on larger resultsets) and should be easier to follow/maintain:USE TempDB;GOIF OBJECT_ID('tempdb.dbo.#temp') IS NOT NULL DROP TABLE #temp;CREATE TABLE #temp( CustNo INT, CustomerName VARCHAR(50), PolEffDate DATETIME, PolExpDate DATETIME, EffDate DATETIME, Description VARCHAR(50));INSERT #tempVALUES ('274', 'Smart, Susan', '2/6/14 12:00:00 AM', '2/6/15 12:00:00 AM', '11/15/14 12:00:00 AM', 'Reinstatement'), ('274', 'Smart, Susan', '2/6/14 12:00:00 AM', '2/6/15 12:00:00 AM', '10/31/14 12:00:00 AM', 'Cancellation'), ('274', 'Smart, Susan', '2/6/14 12:00:00 AM', '2/6/15 12:00:00 AM', '8/8/14 12:00:02 AM', 'Reinstatement'), ('274', 'Smart, Susan', '2/6/14 12:00:00 AM', '2/6/15 12:00:00 AM', '8/8/14 12:00:01 AM', 'Cancellation'), ('274', 'Smart, Susan', '2/6/14 12:00:00 AM', '2/6/15 12:00:00 AM', '2/6/14 12:00:00 AM', 'New');-- We only care about the last entry on each dayWITH cteCollapseToDateAS(select t.CustNo, t.CustomerName, CONVERT(DATE,t.PolExpDate) AS PolExpDate, CONVERT(DATE,t.EffDate) AS EffDateOnly, CASE WHEN t.Description IN ('Reinstatement','New') THEN 1 ELSE 0 END AS isActive, ROW_NUMBER() OVER(PARTITION BY t.CustNo,CONVERT(DATE,t.EffDate) ORDER BY t.EffDate DESC) AS RN FROM #temp AS t)-- Filter out invalid rows and sequence the rest, cteSequenceAS(SELECT t.CustNo, t.CustomerName, t.PolExpDate, t.EffDateOnly, t.isActive, ROW_NUMBER() OVER(PARTITION BY t.CustNo ORDER BY t.EffDateOnly) AS SequenceFROM cteCollapseToDate AS tWHERE t.RN = 1)SELECT t1.CustNo, t1.CustomerName, t1.EffDateOnly AS PeriodStart, COALESCE(t2.EffDateOnly,t1.PolExpDate) AS PeriodEnd, t1.isActiveFROM cteSequence AS t1LEFT JOIN cteSequence AS t2ON t1.CustNo = t2.CustNoAND t1.Sequence = t2.Sequence-1ORDER BY t1.Sequence;/*CustNo CustomerName PeriodStart PeriodEnd isActive274 Smart, Susan 2014-02-06 2014-08-08 1274 Smart, Susan 2014-08-08 2014-10-31 1274 Smart, Susan 2014-10-31 2014-11-15 0274 Smart, Susan 2014-11-15 2015-02-06 1*/ The reason it is faster is because it reduces the reads significantly. |
|
|
|
|
|