Please start any new threads on our new site at https://forums.sqlteam.com. We've got lots of great SQL Server experts to answer whatever question you can come up with.

 All Forums
 SQL Server 2008 Forums
 Transact-SQL (2008)
 Receive the max date for the first occurence

Author  Topic 

v05322
Starting Member

4 Posts

Posted - 2011-05-09 : 14:21:21
I need to receive the max date for the first occurence of a specific code within the same account.

Table:
Account Code Date
123456 INBND 10/15/2010 1:43:00 PM
123456 CICBND 10/15/2010 1:45:00 PM
123456 CICBND 10/15/2010 1:55:00 PM
123456 CICBND 10/16/2010 6:53:00 PM
123456 OTBND 10/17/2010 11:17:00 PM
123456 CICBND 10/22/2010 5:29:00 PM
123456 OTBND 10/25/2010 9:15:00 AM

I want to return the max date for the first occurence of the code equal to CICBND for account 123456.

Results:
Account Code Date
123456 CICBND 10/16/2010 6:53:00 PM

Hope you can help. I keep returning the date for the max occurance of the code which is 10/22/2010 5:29:00 PM instead of the 10/16/2010 date.

ajthepoolman
Constraint Violating Yak Guru

384 Posts

Posted - 2011-05-09 : 14:36:07
According to your dataset the top date should be the 10/22 date. Unless I missed something...

Hey, it compiles.
Go to Top of Page

nigelrivett
Master Smack Fu Yak Hacker

3385 Posts

Posted - 2011-05-09 : 14:41:36
I think you might be looking for the last ocurrance of the first sequence - i.e. take the first entry for the code then find the last entry before another code

==========================================
Cursors are useful if you don't know sql.
SSIS can be used in a similar way.
Beer is not cold and it isn't fizzy.
Go to Top of Page

v05322
Starting Member

4 Posts

Posted - 2011-05-09 : 14:56:38
quote:
Originally posted by ajthepoolman

According to your dataset the top date should be the 10/22 date. Unless I missed something...

Hey, it compiles.



Well, I want the max date for the first grouping of the code 'CICBND'. So, in this example I want to return 10/16/2011 because the code changed to 'OTBND', therefore I don't care about the remaining 'CICBND' records.
Go to Top of Page

v05322
Starting Member

4 Posts

Posted - 2011-05-09 : 15:04:04
quote:
Originally posted by nigelrivett

I think you might be looking for the last ocurrance of the first sequence - i.e. take the first entry for the code then find the last entry before another code

==========================================
Cursors are useful if you don't know sql.
SSIS can be used in a similar way.
Beer is not cold and it isn't fizzy.



Yes, this is correct. I think we are saying the same thing just worded differently.

I am trying to accomplish this in SQL vs other tools. I have tried to use different functions like rank, row_num and others and get very close. Any ideas would be great!
Go to Top of Page

jimf
Master Smack Fu Yak Hacker

2875 Posts

Posted - 2011-05-09 : 15:35:03
;with cte as
(select *,row = row_number() over(order by date)
from #table
)

select top 1 * from cte c
where c.code = 'CICBND'
and exists
(select *
from cte c2 where c2.row = c.row + 1 and c2.code <> c.code
)

Jim


Everyday I learn something that somebody else already knew
Go to Top of Page

TG
Master Smack Fu Yak Hacker

6065 Posts

Posted - 2011-05-09 : 15:47:30
Another option. This returns for each account/Code even if it is the only code in the sequence:
(it's kind of ugly though :)

declare @t table (Account int, Code varchar(15), Dt datetime)
insert @t
select 123456, 'INBND', '10/15/2010 1:43:00 PM' union all
select 123456, 'CICBND', '10/15/2010 1:45:00 PM' union all
select 123456, 'CICBND', '10/15/2010 1:55:00 PM' union all
select 123456, 'CICBND', '10/16/2010 6:53:00 PM' union all
select 123456, 'OTBND', '10/17/2010 11:17:00 PM' union all
select 123456, 'CICBND', '10/22/2010 5:29:00 PM' union all
select 123456, 'OTBND', '10/25/2010 9:15:00 AM'

;with
c1 as (
select account
,code
,dt
,row_number() over (partition by account order by dt) rn
from @t
)
,c2 as (
select account
,code
,min(rn) rn
from c1
group by account
,code
)
,c3 as (
select c1.account
,c2.code
,min(c1.rn) rn
from c2
join c1
on c1.account = c2.account
and c1.code != c2.code
and c1.rn > c2.rn
group by c1.account
,c2.code
)
select c1.account
,c1.code
,max(dt) date
from c3
join c1
on c1.account = c3.account
and c1.code = c3.code
and c1.rn < c3.rn
group by c1.account
,c1.code


OUTPUT:

account code date
----------- --------------- -----------------------
123456 CICBND 2010-10-16 18:53:00.000
123456 INBND 2010-10-15 13:43:00.000
123456 OTBND 2010-10-17 23:17:00.000


Be One with the Optimizer
TG
Go to Top of Page

Lamprey
Master Smack Fu Yak Hacker

4614 Posts

Posted - 2011-05-09 : 16:10:29
Here is another way using sequential groups (using sample data provided by TG):
;WITH cte AS
(
SELECT
*,
ROW_NUMBER() OVER (ORDER BY DT)
- ROW_NUMBER() OVER (PARTITION BY CODE ORDER BY DT) AS GroupSequence
FROM
@t
)

SELECT
MAX(dt) AS MaxDate
FROM cte
WHERE
GroupSequence =
(
SELECT MIN(GroupSequence)
FROM cte
WHERE
Code = 'CICBND'
AND Account = 123456
)
Go to Top of Page

v05322
Starting Member

4 Posts

Posted - 2011-05-09 : 16:59:06
Thanks everyone for the great responses. This is exactly what I was trying to accomplish!
Go to Top of Page
   

- Advertisement -