Kenji776
Kenji776

Reputation: 121

SQL Server find datediff between different rows

I am trying to build a query that analyzes data in our time tracking system. Every time a user punches in or out, it makes a row recording the punch time. So if you punch in at 9:00 and punch out at 5:00 there are two rows with those date stamps recorded accordingly. I need a query that will iterate over the rows at basically sum the datediff between workingpunch_ts (the timestamp column) in hours.

Each row does have an identifier that signifies if the punch is a punch in, or punch out (inout_id, 1 for in, 2 for out).

So for example if you had

ID  | workingpunch_ts         | inout_id
----------------------------------------------
123 | 2011-02-16 09:00:00.000 | 1
124 | 2011-02-16 17:00:00.000 | 2

That would yield a 8 hours. Now I just need to repeat that process for every pair of rows in the table.

Thoughts on how to accomplish this?

Upvotes: 1

Views: 3277

Answers (2)

RichardTheKiwi
RichardTheKiwi

Reputation: 107696

In hours, sure

select empid, cast(datediff(d,0,workingpunch_ts) as datetime),
    SUM(case when inout_id = 2 then 1 else -1 end *
    datediff(MI, datediff(d,0,workingpunch_ts), workingpunch_ts))/60.0 as Hours
from clock
where workingpunch_ts between '20110201' and '20110228 23:59:59.999'
group by empid, datediff(d,0,workingpunch_ts)

As long as the in and outs are paired, you add all the outs and remove all the ins, e.g.

 - IN  (9)
 + OUT (12)
 - IN  (13:15)
 + OUT (17)

The main code is in the 2nd and 3rd lines
The datediff-datediff works out the minutes from midnight for each workingpunch_ts, and if it is a punchout, it is made negative using the CASE inout_id statement.

The others are added for real life scenarios where you need to group by employee and day, within a date range.

Upvotes: 0

Decker97
Decker97

Reputation: 1653

This query will give you problems if people punch in and out multiple times on the same day:

Table schema:

CREATE TABLE [dbo].[TimePunch](
    [TimeCardID] [int] IDENTITY(1,1) NOT NULL,
    [PunchTime] [datetime] NOT NULL,
    [InOrOut] [int] NOT NULL,
    [UserID] [int] NOT NULL,
    [DayofPunch] [datetime] NOT NULL,
 CONSTRAINT [PK_TimePunch] PRIMARY KEY CLUSTERED 
(
    [TimeCardID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON, FILLFACTOR = 10) ON [PRIMARY]
) ON [PRIMARY]

Query:

select 
    tIn.UserID,
    tIn.DayOfPunch,
    DateDiff(Hour, tIn.PunchTime, tOut.PunchTime) as HoursWorked
FROM
    TimePunch tIn,
    TimePunch tOut
WHERE
    tIn.InOrOut = 1
AND tOut.InOrOut = 2
AND tIn.UserID = tOut.UserID
AND tIn.DayofPunch = tOut.DayOfPunch

Upvotes: 1

Related Questions