Techies--
I want to retrieve a result set that returns the beginning effective data and end effective date for an id with multiple supplier associations. To do this, I am looking at a transaction table that records the id (lcard), the supplier's id and the date the transaction
occurred. In cases where the id has switched suppliers, I want to retire the old association and record the new association. In instances where I have a transaction, but the id hasn't switched suppliers I want to ignore the row.
What I have works for a single id, however, when I add the second id, the order/partitioning does not work. Instead, I get the rows I want to ignore and in only id grouping I get a null end-date.
Here's what the desired result set would return:
Here's the test script
-- Note: use this to emulate the known switched suppliers table
create table #switched
(lcard bigint);
insert into #switched (lcard) values (700382)
insert into #switched (lcard) values (832019)
select * from #switched
-- Note: this temp data represents a previously grouped/partitioned table
-- prepped for this next phase of action
create table #PartitionTest
( FauxId int,
lcard bigint,
suppId int,
switchDate datetime
);
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (1,700382,506,cast('Jun 23 2013 12:00AM' as datetime))
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (2,700382,49401,cast('May 22 2013 12:00AM' as datetime))
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (3,700382,49401,cast('May 4 2013 12:00AM' as datetime))
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (4,700382,49401,cast('May 2 2013 12:00AM' as datetime))
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (5,700382,49401,cast('Apr 26 2013 12:00AM' as datetime))
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (6,700382,49401,cast('Mar 15 2013 12:00AM' as datetime))
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (1,832019,27088,cast('Jun 18 2013 12:00AM' as datetime))
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (2,832019,232,cast('May 24 2013 12:00AM' as datetime))
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (3,832019,232,cast('May 23 2013 12:00AM' as datetime))
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (4,832019,232,cast('May 22 2013 12:00AM' as datetime))
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (5,832019,232,cast('May 21 2013 12:00AM' as datetime))
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (6,832019,232,cast('May 17 2013 12:00AM' as datetime))
INSERT INTO #PartitionTest (FauxId,lcard,suppId,switchDate) VALUES (7,832019,232,cast('May 16 2013 12:00AM' as datetime))
-- Note: Order results by lcard, then order the supplier id by
-- the transaction date found. FauxId is from the previous partitioning
select * from #PartitionTest
order by lcard,fauxId, suppId, switchDate
-- This is the statement that is failing when attempting to utilize
-- the ids in #switched as the criterion processing sets of ids.
;with sifted
as ( select *,
row_number() over (ORDER BY switchDate) - row_number() over (PARTITION BY lcard, suppId ORDER BY switchDate) as G
from #PartitionTest
where lcard in
(select lcard
from #switched
)
-- // DEBUG TEST: specific card holder(s)
-- NOTE: when both lcards are used, the beginEffDate/endEffDate goal fails by including every transaction
-- and lcard in ('8320198','7003824')
-- NOTE: this represents the intent, notice how the multiple transactions reduce to the last sighting, rather than all occurrances
and lcard in (700382)
),
refined as
(select lcard,
suppId,
MIN(switchDate) BeginEffDate,
ROW_NUMBER() OVER (ORDER BY min(switchDate)) as OrgSplit
from sifted
group by lcard,suppId, G)
select a.lcard,
a.suppId,
a.BeginEffDate,
b.BeginEffDate as EndEffDate
from refined a
left join refined b
on a.OrgSplit + 1 = b.OrgSplit
order by a.lcard, a.suppId
-- drop table #switched;
-- drop table #PartitionTest;