Quantcast
Channel: Transact-SQL forum
Viewing all articles
Browse latest Browse all 23857

SQL: Partitian Over Challenge.

$
0
0

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;




Viewing all articles
Browse latest Browse all 23857

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>