January 17, 2011 at 2:56 am
I have a table that show the working log for a particular users. We can see the Date, Time, CardNumber
Name, StaffNumber and TranCode. TranCode indicate in/out for a particular record.
0 is In while 9 is exit.
Sample data as below:
Date Time CardNumber Name StaffNumber TranCode
------------------------------------------------------------------------------------------
2011-01-04 09:41 1000 Ken 001 0
2011-01-04 10:09 1000 Ken 001 9
2011-01-04 10:26 1000 Ken 001 0
2011-01-04 12:10 1000 Ken 001 9
2011-01-04 12:51 1000 Ken 001 0
2011-01-04 19:00 1000 Ken 001 9
2011-01-04 09:40 1001 Jim 002 0
2011-01-04 11:00 1001 Jim 002 9
2011-01-04 12:00 1001 Jim 002 0
2011-01-04 12:52 1001 Jim 002 9
2011-01-04 14:10 1001 Jim 002 0
2011-01-04 18:30 1001 Jim 002 9
2011-01-05 09:00 1000 Ken 001 0
2011-01-05 19:00 1000 Ken 001 9
my challenge is to come out a report showing the actual working hours for a particular users.
Expected output as below:
Date StarTime EndTime CardNumber Name StaffNumber Duration
----------------------------------------------------------------------------------------------------
2011-01-04 09:41 10:09 1000 Ken 001 0:28
2011-01-04 10:26 12:10 1000 Ken 001 1:44
2011-01-04 12:51 19:00 1000 Ken 001 6:09
2011-01-04 09:40 11:00 1001 Jim 002 1:20
2011-01-04 12:00 12:52 1001 Jim 002 0:52
2011-01-04 14:10 18:30 1001 Jim 002 4:20
2011-01-05 09:00 19:00 1000 Ken 001 10:00
DDL Script as below
declare @logrec table
(Date datetime,
[Time] datetime,
CardNumber varchar(10),
[Name] varchar(50),
StaffNumber varchar(10),
TranCode varchar(2))
insert into @logrec
select '2011-01-04', '09:41','1000','Ken', '001','0' union
select '2011-01-04', '10:09','1000','Ken','001','9'union
select '2011-01-04', '10:26','1000','Ken','001','0'union
select '2011-01-04', '12:10','1000','Ken','001','9'union
select '2011-01-04', '12:10','1000','Ken','001','9'union
select '2011-01-04', '12:51','1000','Ken','001','0'union
select '2011-01-04', '19:00','1000','Ken','001','9'union
select '2011-01-04', '09:40','1001','Jim','002','0'union
select '2011-01-04', '11:00','1001','Jim','002','9'union
select '2011-01-04', '12:00','1001','Jim','002','0'union
select '2011-01-04', '12:52','1001','Jim','002','9'union
select '2011-01-04', '14:10','1001','Jim','002','0'union
select '2011-01-04', '18:30','1001','Jim','002','9'union
select '2011-01-05', '09:00','1000','Ken','001','0'union
select '2011-01-05', '19:00','1000','Ken','001','9'
I have tried many ways but still unable to find out the solutions. Appreciate if you can give me a hand..
if you have a difficulty to view the sample data, please download the attachments.
Thanks
January 17, 2011 at 3:21 am
SELECT CONVERT(CHAR(10),s.Date,120) AS Date,
CONVERT(CHAR(5),s.Time,108) AS StarTime,
CONVERT(CHAR(5),e.Time,108) AS EndTime,
s.CardNumber,
s.Name,
s.StaffNumber,
CAST(DATEDIFF(minute,s.Time,e.Time)/60 AS VARCHAR(10)) + ':' +
RIGHT(CAST(100+DATEDIFF(minute,s.Time,e.Time)%60 AS VARCHAR(3)),2) AS Duration
FROM @logrec s
CROSS APPLY (SELECT TOP 1 e.Time FROM @logrec e
WHERE e.TranCode='9'
AND e.Date=s.Date
AND e.CardNumber=s.CardNumber
AND e.Name=s.Name
AND e.Time>s.Time
ORDER BY e.Time) e
WHERE s.TranCode='0'
ORDER BY s.Date,s.CardNumber,s.Time;
____________________________________________________
Deja View - The strange feeling that somewhere, sometime you've optimised this query before
How to get the best help on a forum
http://www.sqlservercentral.com/articles/Best+Practices/61537January 17, 2011 at 8:35 pm
Thanks for the solutions .. now i having a new issues, i try to summarizing data with rollup in order to get the total amount of durations for each employees, but received an error message because sum function only works with numeric data types. Anyone can give a hand ??
January 17, 2011 at 10:08 pm
sqlbaby2 (1/17/2011)
Thanks for the solutions .. now i having a new issues, i try to summarizing data with rollup in order to get the total amount of durations for each employees, but received an error message because sum function only works with numeric data types. Anyone can give a hand ??
Sure... let's really get off on the right foot, though. Please read the first link in my signature line below. If you post data that way, it will really help us help you a lot.,
Second, post the code you've tried. It will first let us see what you're doing (right or wrong) and it will also convince us that you've given it the ol' college try. 🙂
--Jeff Moden
Change is inevitable... Change for the better is not.
January 17, 2011 at 10:11 pm
I already found the solutions ...thanks
January 17, 2011 at 11:06 pm
sqlbaby2 (1/17/2011)
I already found the solutions ...thanks
In that case, would you mind sharing them? Two way street here... 😉
And... you should still read the article I pointed you to. It'll help you get better, tested solutions faster no matter which forum you post on. :w00t:
--Jeff Moden
Change is inevitable... Change for the better is not.
January 18, 2011 at 7:47 am
SELECT A.Date,A.CardNumber,A.Name,A.StaffNumber,
CASE WHEN LEN(CAST(SUM(A.DurNum)/60 AS VARCHAR(10))) = 1
THEN '0'+LTRIM(STR(CAST(SUM(A.DurNum)/60 AS VARCHAR(10)),3)) +':'+
CAST(SUM(A.DurNum)%60 AS VARCHAR(3))
ELSE LTRIM(STR(CAST(SUM(A.DurNum)/60 AS VARCHAR(10)),3)) +':'+
RIGHT(100+CAST(SUM(A.DurNum)%60 AS VARCHAR(3)),2)
END N
FROM (
SELECT CONVERT(CHAR(10),s.Date,120) AS Date,
CONVERT(CHAR(5),s.Time,108) AS StarTime,
CONVERT(CHAR(5),e.Time,108) AS EndTime,
s.CardNumber,
s.Name,
s.StaffNumber,
CASE WHEN LEN(CAST(DATEDIFF(minute,s.Time,e.Time)/60 AS VARCHAR(10))) = 1
THEN '0'+LTRIM(STR(CAST(DATEDIFF(minute,s.Time,e.Time)/60 AS VARCHAR(10)),2))+':'+
RIGHT(100+CAST(DATEDIFF(minute,s.Time,e.Time)%60 AS VARCHAR(3)),2)
ELSE LTRIM(STR(CAST(DATEDIFF(minute,s.Time,e.Time)/60 AS VARCHAR(10)),2))+':'+
RIGHT(100+CAST(DATEDIFF(minute,s.Time,e.Time)%60 AS VARCHAR(3)),2)
END Duration,
CAST(DATEDIFF(minute,s.Time,e.Time)/60 AS INT)*60+
CAST(RIGHT(CAST(DATEDIFF(minute,s.Time,e.Time)%60 AS VARCHAR(3)),2) AS INT) AS DurNum
FROM @logrec s
CROSS APPLY (SELECT TOP 1 e.Time FROM @logrec e
WHERE e.TranCode='9'
AND e.Date=s.Date
AND e.CardNumber=s.CardNumber
AND e.Name=s.Name
AND e.Time>s.Time
ORDER BY e.Time) e
WHERE s.TranCode='0') A
GROUP BY A.Date,A.CardNumber,A.Name,A.StaffNumber
ORDER BY a.Date,a.CardNumber;
January 20, 2011 at 8:07 pm
Thanks for posting the code.
--Jeff Moden
Change is inevitable... Change for the better is not.
Viewing 8 posts - 1 through 7 (of 7 total)
You must be logged in to reply to this topic. Login to reply