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
 General SQL Server Forums
 New to SQL Server Programming
 Row_Number() Over Partition By()

Author  Topic 

edyl
Starting Member

35 Posts

Posted - 2014-07-30 : 18:37:12
Hello Everyone,

I have Logs table and want to assign a serial number to the techs using the following query


Select
Date,
Case_ID,
Site,
Dept,
Tech,
Start_Time,
ROW_NUMBER () OVER (PARTITION BY Date, Site, Dept, Tech ORDER BY Start_Time) as Row_Num
FROM
Logs
Where Date = Getdate()


I get the following results.

Date Case ID Site Dept Tech Start Time Row_Num
7/28/14 10023 Tartville Maintc Amy P. 7:30 1
7/28/14 56789 Tartville Maintc Rem W. 8:05 1
7/28/14 23098 Tartville Maintc Amy P. 8:35 2
7/28/14 70004 Tartville Maintc Amy P. 9:10 3
7/28/14 12708 Tartville Maintc Mag O. 10:00 1
7/28/14 10004 Tartville Maintc Amy P. 12:30 4
7/28/14 40056 Tartville Service Joe F. 7:30 1
7/28/14 23458 Tartville Service Joe F. 7:55 2
7/28/14 69200 Tartville Service Rus T. 7:30 1


Please notice the cases in Maintc department. See how Amy P.'s shift is broken by Rem W. and Mag O. But the Row Number does not recognize this, it still says Amy P's case as 2 and 4 the even though Rem's and Mag's cases were in between.

This is what I really wanted.

Date Case ID Site Dept Tech Start Time Row_Num
7/28/14 10023 Tartville Maintc Amy P. 7:30 1
7/28/14 56789 Tartville Maintc Rem W. 8:05 1
7/28/14 23098 Tartville Maintc Amy P. 8:35 1
7/28/14 70004 Tartville Maintc Amy P. 9:10 2
7/28/14 12708 Tartville Maintc Mag O. 10:00 1
7/28/14 10004 Tartville Maintc Amy P. 12:30 1
7/28/14 40056 Tartville Service Joe F. 7:30 1
7/28/14 23458 Tartville Service Joe F. 7:55 2
7/28/14 69200 Tartville Service Rus T. 7:30 1


I tried many combination of columns for Partition by () and Order by () and the best I can get is the result at the top. How should I achieve it. Any suggestions and recommendations in this matter would be greatly appreciated.

Thanks,

Bustaz Kool
Master Smack Fu Yak Hacker

1834 Posts

Posted - 2014-08-01 : 19:06:15
I don't know how performant this will be but...
declare @Logs table (
Date date,
Case_ID varchar(20),
Site varchar(20),
Dept varchar(20),
Tech varchar(20),
Start_Time time
)

insert into @Logs
values
('7/28/14', '10023', 'Tartville', 'Maintc', 'Amy P.', '7:30'),
('7/28/14', '56789', 'Tartville', 'Maintc', 'Rem W.', '8:05'),
('7/28/14', '23098', 'Tartville', 'Maintc', 'Amy P.', '8:35'),
('7/28/14', '70004', 'Tartville', 'Maintc', 'Amy P.', '9:10'),
('7/28/14', '12708', 'Tartville', 'Maintc', 'Mag O.', '10:00'),
('7/28/14', '10004', 'Tartville', 'Maintc', 'Amy P.', '12:30'),
('7/28/14', '40056', 'Tartville', 'Service', 'Joe F.', '7:30'),
('7/28/14', '23458', 'Tartville', 'Service', 'Joe F.', '7:55'),
('7/28/14', '69200', 'Tartville', 'Service', 'Rus T. ', '7:30')

--/**/ select * from @Logs

;with Logs
as (
select l.*, dense_rank() over (partition by l.Date, l.Site, l.Dept order by l.start_time) rnk
from @Logs l
)
--select * from Logs
,Ranges
as (
select
l.Date,
--l.Case_ID,
l.Site,
l.Dept,
l.Tech,
l.start_time,
u.start_time End_time,
row_number() over(order by l.start_time) rn
from
Logs l -- l = lower edge of range
inner join
Logs u -- u = upper edge of range
on l.Date = u.Date
and l.Site = u.Site
and l.Dept = u.Dept
and l.Tech = u.Tech
and l.Start_Time <= u.Start_Time
and not exists ( -- where there is not an intervening tech
select *
from Logs m
where
l.Date = m.Date
and l.Site = m.Site
and l.Dept = m.Dept
and l.Tech <> m.Tech
and l.Start_Time < m.Start_Time and m.Start_Time <u.Start_Time
)
and not exists ( -- not a smaller lower edge in this range
select *
from Logs ll
where
ll.Date = l.Date
and ll.Site = l.Site
and ll.Dept = l.Dept
and ll.Tech = l.Tech
and ll.rnk = l.rnk - 1
)
and not exists ( -- not a bigger upper edge of this range
select *
from Logs uu
where
uu.Date = u.Date
and uu.Site = u.Site
and uu.Dept = u.Dept
and uu.Tech = u.Tech
and uu.rnk = u.rnk + 1
)
)
--select * from ranges
select
l.*,
row_number() over (partition by r.rn order by l.start_time) row_num
from
@Logs l
inner join
Ranges r
on r.Date = l.Date
and r.Site = l.Site
and r.Dept = l.Dept
and r.Tech = l.Tech
and l.Start_Time between r.Start_Time and r.End_time
order by
l.Dept,
l.Tech,
l.Start_Time
hth



Too often we enjoy the comfort of opinion without the discomfort of thought. - John F. Kennedy
Go to Top of Page
   

- Advertisement -