Using SQL Server 2005, I have a table that records the datetime
that a user clocks out of their shift. It stores these values in a datetime
column.
Sometimes people have mistakenly clocked out of their shift early and then they clock out again at the right time.
I have been tasked with pulling all of the dates that a user left early for the day. There are some days that have two entries and I have to get the maximum entry for that day. They may have clocked out at the right time for the second time, but their first time is still in there.
So, there is a table that is called tblShift
that has the time that they are supposed to clock out. This is tblShift
. The datetime value is tblShift.ShiftEnd
.
Then there is the table tblCLock
that shows their types of clockouts. These could be breaks or actually clocking out at the end of their shift, or a mistaken clock out.
This is the WRONG way I am doing it:
SELECT
clockDateTime,
datediff(n, tblShift.ShiftEnd, tblClock.ClockDateTime) as minutes
from
tblClock
INNER JOIN
tblShift ON tblClock.userid = tblShift.userid
AND Year(tblClock.ClockDateTime) = Year(tblShift.ShiftEnd)
AND Month(tblClock.ClockDateTime) = Month(tblShift.ShiftEnd)
AND Day(tblClock.ClockDateTime) = Day(tblShift.ShiftEnd)
WHERE
tblClock.USERID = 29689 --one of the id's in the table
and clocktypeid = 1
and clockstatusid = 2
and tblShift.ShiftEnd between '2011-11-11 12:00:00 AM' and '2012-11-11 11:59:59 PM'
and tblShift.ShiftTypeID = 1
and datediff(n, tblShift.ShiftEnd, tblClock.ClockDateTime) < 0
ORDER BY
tblClock.clockdatetime desc
What happens there is that the mistaken early clock out is used on the days that they clocked out by mistake and then clocked out at the proper time at the end of their shift.
I am trying to figure out how to work MAX into this query so that I am only getting the maximum from each day.
I have started over a few times and am not succeeding.
tblClock:
[clockID] [int] IDENTITY(1,1) NOT NULL,
[clockStatusID] [int] NULL,
[clockTypeID] [int] NULL,
[userID] [int] NULL,
[clockDateTime] [datetime] NULL CONSTRAINT [DF_tblClock_clockDateTime] DEFAULT (getdate()),
[clockNotes] [text] NULL,
tblShift:
[shiftID] [int] IDENTITY(1,1) NOT NULL,
[shiftTypeID] [int] NULL CONSTRAINT [DF_tblShift_shiftTypeID] DEFAULT ((1)),
[userID] [int] NULL,
[shiftStart] [datetime] NULL,
[shiftEnd] [datetime] NULL,
[shiftNotes] [text] NULL,
UPDATE: I have been working on this most of a day, and have gotten it to this point:
SELECT
max(tblClock.clockdatetime) as clockdatetime,
max(tblShift.ShiftEnd),
datediff(n, max(tblShift.ShiftEnd), max(tblClock.ClockDateTime)) as minutes
FROM
tblclock
INNER JOIN
tblShift ON tblClock.userid = tblShift.userid
AND Year(tblClock.ClockDateTime) = Year(tblShift.ShiftEnd)
AND Month(tblClock.ClockDateTime) = Month(tblShift.ShiftEnd)
AND Day(tblClock.ClockDateTime) = Day(tblShift.ShiftEnd)
WHERE
tblClock.userid = 29689
AND
tblClock.clocktypeid = 1
AND
tblClock.clockstatusid = 2
AND
tblShift.ShiftEnd between '2011-10-01 12:00:00 AM' AND '2012-10-01 11:59:59 PM'
AND
tblShift.ShiftTypeID = 1
GROUP BY
Year(tblClock.clockdatetime),Month(tblClock.clockdatetime),day(tblClock.clockdatetime)
ORDER BY
max(tblClock.clockdatetime) desc
I am using my scripting language to only display those with minutes less than zero, because I can't get the AND Minutes < 0 into the where portion.
Also, thank you for the edit to properly word the question. Marching on...