Find first day per group where time spans midnight boundaries
I have a table that calculates what hours a person has worked. We have a night team that logon anytime after 4PM and logoff before 8AM the following morning. The table looks like the below.
Workdate WorkHour
2018-11-13 20 -- this was the hour they logged on
2018-11-13 21
2018-11-13 22
2018-11-13 23
2018-11-14 0
2018-11-14 1
2018-11-14 2
2018-11-14 3
2018-11-14 4
2018-11-14 5 -- this was the hour they logged off
For the purpose of reporting, we only want to associate these hours worked to the date they first logged on, in this example the 13th of November 2018. My ideal output would look like the below.
Workdate WorkHour ReportingDate
2018-11-13 20 2018-11-13
2018-11-13 21 2018-11-13
2018-11-13 22 2018-11-13
2018-11-13 23 2018-11-13
2018-11-14 0 2018-11-13
2018-11-14 1 2018-11-13
2018-11-14 2 2018-11-13
2018-11-14 3 2018-11-13
2018-11-14 4 2018-11-13
2018-11-14 5 2018-11-13
Any ideas on how I can do this? Appreciate any help
Jess
sql sql-server datetime sql-server-2012 gaps-and-islands
add a comment |
I have a table that calculates what hours a person has worked. We have a night team that logon anytime after 4PM and logoff before 8AM the following morning. The table looks like the below.
Workdate WorkHour
2018-11-13 20 -- this was the hour they logged on
2018-11-13 21
2018-11-13 22
2018-11-13 23
2018-11-14 0
2018-11-14 1
2018-11-14 2
2018-11-14 3
2018-11-14 4
2018-11-14 5 -- this was the hour they logged off
For the purpose of reporting, we only want to associate these hours worked to the date they first logged on, in this example the 13th of November 2018. My ideal output would look like the below.
Workdate WorkHour ReportingDate
2018-11-13 20 2018-11-13
2018-11-13 21 2018-11-13
2018-11-13 22 2018-11-13
2018-11-13 23 2018-11-13
2018-11-14 0 2018-11-13
2018-11-14 1 2018-11-13
2018-11-14 2 2018-11-13
2018-11-14 3 2018-11-13
2018-11-14 4 2018-11-13
2018-11-14 5 2018-11-13
Any ideas on how I can do this? Appreciate any help
Jess
sql sql-server datetime sql-server-2012 gaps-and-islands
You're going to need to use a window function. Do you have a field that uniquely identifies one of the employees? Like a UserId?
– Jim Jimson
Nov 15 '18 at 10:58
Yep we have a userID and a Username field
– Jess8766
Nov 15 '18 at 10:59
Can we assume that a person never stays more than 23 hours?
– Salman A
Nov 15 '18 at 11:32
This is correct
– Jess8766
Nov 15 '18 at 11:37
add a comment |
I have a table that calculates what hours a person has worked. We have a night team that logon anytime after 4PM and logoff before 8AM the following morning. The table looks like the below.
Workdate WorkHour
2018-11-13 20 -- this was the hour they logged on
2018-11-13 21
2018-11-13 22
2018-11-13 23
2018-11-14 0
2018-11-14 1
2018-11-14 2
2018-11-14 3
2018-11-14 4
2018-11-14 5 -- this was the hour they logged off
For the purpose of reporting, we only want to associate these hours worked to the date they first logged on, in this example the 13th of November 2018. My ideal output would look like the below.
Workdate WorkHour ReportingDate
2018-11-13 20 2018-11-13
2018-11-13 21 2018-11-13
2018-11-13 22 2018-11-13
2018-11-13 23 2018-11-13
2018-11-14 0 2018-11-13
2018-11-14 1 2018-11-13
2018-11-14 2 2018-11-13
2018-11-14 3 2018-11-13
2018-11-14 4 2018-11-13
2018-11-14 5 2018-11-13
Any ideas on how I can do this? Appreciate any help
Jess
sql sql-server datetime sql-server-2012 gaps-and-islands
I have a table that calculates what hours a person has worked. We have a night team that logon anytime after 4PM and logoff before 8AM the following morning. The table looks like the below.
Workdate WorkHour
2018-11-13 20 -- this was the hour they logged on
2018-11-13 21
2018-11-13 22
2018-11-13 23
2018-11-14 0
2018-11-14 1
2018-11-14 2
2018-11-14 3
2018-11-14 4
2018-11-14 5 -- this was the hour they logged off
For the purpose of reporting, we only want to associate these hours worked to the date they first logged on, in this example the 13th of November 2018. My ideal output would look like the below.
Workdate WorkHour ReportingDate
2018-11-13 20 2018-11-13
2018-11-13 21 2018-11-13
2018-11-13 22 2018-11-13
2018-11-13 23 2018-11-13
2018-11-14 0 2018-11-13
2018-11-14 1 2018-11-13
2018-11-14 2 2018-11-13
2018-11-14 3 2018-11-13
2018-11-14 4 2018-11-13
2018-11-14 5 2018-11-13
Any ideas on how I can do this? Appreciate any help
Jess
sql sql-server datetime sql-server-2012 gaps-and-islands
sql sql-server datetime sql-server-2012 gaps-and-islands
edited Nov 26 '18 at 11:57
Salman A
184k67342439
184k67342439
asked Nov 15 '18 at 10:52
Jess8766Jess8766
717
717
You're going to need to use a window function. Do you have a field that uniquely identifies one of the employees? Like a UserId?
– Jim Jimson
Nov 15 '18 at 10:58
Yep we have a userID and a Username field
– Jess8766
Nov 15 '18 at 10:59
Can we assume that a person never stays more than 23 hours?
– Salman A
Nov 15 '18 at 11:32
This is correct
– Jess8766
Nov 15 '18 at 11:37
add a comment |
You're going to need to use a window function. Do you have a field that uniquely identifies one of the employees? Like a UserId?
– Jim Jimson
Nov 15 '18 at 10:58
Yep we have a userID and a Username field
– Jess8766
Nov 15 '18 at 10:59
Can we assume that a person never stays more than 23 hours?
– Salman A
Nov 15 '18 at 11:32
This is correct
– Jess8766
Nov 15 '18 at 11:37
You're going to need to use a window function. Do you have a field that uniquely identifies one of the employees? Like a UserId?
– Jim Jimson
Nov 15 '18 at 10:58
You're going to need to use a window function. Do you have a field that uniquely identifies one of the employees? Like a UserId?
– Jim Jimson
Nov 15 '18 at 10:58
Yep we have a userID and a Username field
– Jess8766
Nov 15 '18 at 10:59
Yep we have a userID and a Username field
– Jess8766
Nov 15 '18 at 10:59
Can we assume that a person never stays more than 23 hours?
– Salman A
Nov 15 '18 at 11:32
Can we assume that a person never stays more than 23 hours?
– Salman A
Nov 15 '18 at 11:32
This is correct
– Jess8766
Nov 15 '18 at 11:37
This is correct
– Jess8766
Nov 15 '18 at 11:37
add a comment |
3 Answers
3
active
oldest
votes
You can think of it as a gaps and island problem where contiguous hours represent an island. You need to find all islands and find minimum date for each island:
DECLARE @T TABLE (userid INT, workdate DATE, workhour INT);
INSERT INTO @t VALUES
(1, '2018-11-13', 20),
(1, '2018-11-13', 21),
(1, '2018-11-13', 22),
(1, '2018-11-13', 23),
(1, '2018-11-14', 0),
(1, '2018-11-14', 1),
(1, '2018-11-14', 2),
(1, '2018-11-14', 3),
(1, '2018-11-14', 4),
(1, '2018-11-14', 5),
(1, '2018-11-20', 6);
WITH cte1 AS (
SELECT userid, workdate, workhour
, DATEADD(HOUR, workhour, CAST(workdate AS DATETIME)) AS workdatetime
FROM @t
), cte2 AS (
SELECT userid, workdate, workhour
, CASE WHEN DATEDIFF(HOUR, LAG(workdatetime) OVER (PARTITION BY userid ORDER BY workdate, workhour), workdatetime) = 1 THEN 0 ELSE 1 END AS chg
FROM cte1
), cte3 AS (
SELECT userid, workdate, workhour
, SUM(chg) OVER (PARTITION BY userid ORDER BY workdate, workhour) AS grp
FROM cte2
)
SELECT userid, workdate, workhour, MIN(workdate) OVER (PARTITION BY userid, grp) AS ReportingDate
FROM cte3
ORDER BY userid, workdate, workhour
add a comment |
I'll update when I've got a working example, but try:
SELECT
MIN(WorkDate) OVER (PARTITION BY UserId ORDER BY WorkHour) [ReportingDate]
FROM <YourTable>
WHERE WorkDate >= CAST(DATEADD(DAY, -1, GETDATE()) AS DATE)
This will be a historical report so it might be run sometimes for a period in the past, ie last week.
– Jess8766
Nov 15 '18 at 11:39
Is there a shift ID or something that identifies a shift?
– Jim Jimson
Nov 15 '18 at 18:04
add a comment |
This is a variation of "gaps-and-islands". You can identify the adjacent hours by subtracting an enumerated sequence. After that, you just need to take the max over the group.
select t.*,
min(workdate) over (partition by datediff(hour, - seqnum, workdatehour) as imputed_workdate
from (select t.*,
dateadd(hour, workhour, workdate) as workdatehour,
row_number() over (order by workdate, workhour) as seqnum
from t
) t
datediff(day,
needs to bedateadd(hour,
.
– Salman A
Nov 15 '18 at 12:16
@SalmanA . . . Thank you.
– Gordon Linoff
Nov 15 '18 at 13:25
add a comment |
Your Answer
StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");
StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);
else
createEditor();
);
function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53317810%2ffind-first-day-per-group-where-time-spans-midnight-boundaries%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
You can think of it as a gaps and island problem where contiguous hours represent an island. You need to find all islands and find minimum date for each island:
DECLARE @T TABLE (userid INT, workdate DATE, workhour INT);
INSERT INTO @t VALUES
(1, '2018-11-13', 20),
(1, '2018-11-13', 21),
(1, '2018-11-13', 22),
(1, '2018-11-13', 23),
(1, '2018-11-14', 0),
(1, '2018-11-14', 1),
(1, '2018-11-14', 2),
(1, '2018-11-14', 3),
(1, '2018-11-14', 4),
(1, '2018-11-14', 5),
(1, '2018-11-20', 6);
WITH cte1 AS (
SELECT userid, workdate, workhour
, DATEADD(HOUR, workhour, CAST(workdate AS DATETIME)) AS workdatetime
FROM @t
), cte2 AS (
SELECT userid, workdate, workhour
, CASE WHEN DATEDIFF(HOUR, LAG(workdatetime) OVER (PARTITION BY userid ORDER BY workdate, workhour), workdatetime) = 1 THEN 0 ELSE 1 END AS chg
FROM cte1
), cte3 AS (
SELECT userid, workdate, workhour
, SUM(chg) OVER (PARTITION BY userid ORDER BY workdate, workhour) AS grp
FROM cte2
)
SELECT userid, workdate, workhour, MIN(workdate) OVER (PARTITION BY userid, grp) AS ReportingDate
FROM cte3
ORDER BY userid, workdate, workhour
add a comment |
You can think of it as a gaps and island problem where contiguous hours represent an island. You need to find all islands and find minimum date for each island:
DECLARE @T TABLE (userid INT, workdate DATE, workhour INT);
INSERT INTO @t VALUES
(1, '2018-11-13', 20),
(1, '2018-11-13', 21),
(1, '2018-11-13', 22),
(1, '2018-11-13', 23),
(1, '2018-11-14', 0),
(1, '2018-11-14', 1),
(1, '2018-11-14', 2),
(1, '2018-11-14', 3),
(1, '2018-11-14', 4),
(1, '2018-11-14', 5),
(1, '2018-11-20', 6);
WITH cte1 AS (
SELECT userid, workdate, workhour
, DATEADD(HOUR, workhour, CAST(workdate AS DATETIME)) AS workdatetime
FROM @t
), cte2 AS (
SELECT userid, workdate, workhour
, CASE WHEN DATEDIFF(HOUR, LAG(workdatetime) OVER (PARTITION BY userid ORDER BY workdate, workhour), workdatetime) = 1 THEN 0 ELSE 1 END AS chg
FROM cte1
), cte3 AS (
SELECT userid, workdate, workhour
, SUM(chg) OVER (PARTITION BY userid ORDER BY workdate, workhour) AS grp
FROM cte2
)
SELECT userid, workdate, workhour, MIN(workdate) OVER (PARTITION BY userid, grp) AS ReportingDate
FROM cte3
ORDER BY userid, workdate, workhour
add a comment |
You can think of it as a gaps and island problem where contiguous hours represent an island. You need to find all islands and find minimum date for each island:
DECLARE @T TABLE (userid INT, workdate DATE, workhour INT);
INSERT INTO @t VALUES
(1, '2018-11-13', 20),
(1, '2018-11-13', 21),
(1, '2018-11-13', 22),
(1, '2018-11-13', 23),
(1, '2018-11-14', 0),
(1, '2018-11-14', 1),
(1, '2018-11-14', 2),
(1, '2018-11-14', 3),
(1, '2018-11-14', 4),
(1, '2018-11-14', 5),
(1, '2018-11-20', 6);
WITH cte1 AS (
SELECT userid, workdate, workhour
, DATEADD(HOUR, workhour, CAST(workdate AS DATETIME)) AS workdatetime
FROM @t
), cte2 AS (
SELECT userid, workdate, workhour
, CASE WHEN DATEDIFF(HOUR, LAG(workdatetime) OVER (PARTITION BY userid ORDER BY workdate, workhour), workdatetime) = 1 THEN 0 ELSE 1 END AS chg
FROM cte1
), cte3 AS (
SELECT userid, workdate, workhour
, SUM(chg) OVER (PARTITION BY userid ORDER BY workdate, workhour) AS grp
FROM cte2
)
SELECT userid, workdate, workhour, MIN(workdate) OVER (PARTITION BY userid, grp) AS ReportingDate
FROM cte3
ORDER BY userid, workdate, workhour
You can think of it as a gaps and island problem where contiguous hours represent an island. You need to find all islands and find minimum date for each island:
DECLARE @T TABLE (userid INT, workdate DATE, workhour INT);
INSERT INTO @t VALUES
(1, '2018-11-13', 20),
(1, '2018-11-13', 21),
(1, '2018-11-13', 22),
(1, '2018-11-13', 23),
(1, '2018-11-14', 0),
(1, '2018-11-14', 1),
(1, '2018-11-14', 2),
(1, '2018-11-14', 3),
(1, '2018-11-14', 4),
(1, '2018-11-14', 5),
(1, '2018-11-20', 6);
WITH cte1 AS (
SELECT userid, workdate, workhour
, DATEADD(HOUR, workhour, CAST(workdate AS DATETIME)) AS workdatetime
FROM @t
), cte2 AS (
SELECT userid, workdate, workhour
, CASE WHEN DATEDIFF(HOUR, LAG(workdatetime) OVER (PARTITION BY userid ORDER BY workdate, workhour), workdatetime) = 1 THEN 0 ELSE 1 END AS chg
FROM cte1
), cte3 AS (
SELECT userid, workdate, workhour
, SUM(chg) OVER (PARTITION BY userid ORDER BY workdate, workhour) AS grp
FROM cte2
)
SELECT userid, workdate, workhour, MIN(workdate) OVER (PARTITION BY userid, grp) AS ReportingDate
FROM cte3
ORDER BY userid, workdate, workhour
edited Nov 15 '18 at 12:11
answered Nov 15 '18 at 11:52
Salman ASalman A
184k67342439
184k67342439
add a comment |
add a comment |
I'll update when I've got a working example, but try:
SELECT
MIN(WorkDate) OVER (PARTITION BY UserId ORDER BY WorkHour) [ReportingDate]
FROM <YourTable>
WHERE WorkDate >= CAST(DATEADD(DAY, -1, GETDATE()) AS DATE)
This will be a historical report so it might be run sometimes for a period in the past, ie last week.
– Jess8766
Nov 15 '18 at 11:39
Is there a shift ID or something that identifies a shift?
– Jim Jimson
Nov 15 '18 at 18:04
add a comment |
I'll update when I've got a working example, but try:
SELECT
MIN(WorkDate) OVER (PARTITION BY UserId ORDER BY WorkHour) [ReportingDate]
FROM <YourTable>
WHERE WorkDate >= CAST(DATEADD(DAY, -1, GETDATE()) AS DATE)
This will be a historical report so it might be run sometimes for a period in the past, ie last week.
– Jess8766
Nov 15 '18 at 11:39
Is there a shift ID or something that identifies a shift?
– Jim Jimson
Nov 15 '18 at 18:04
add a comment |
I'll update when I've got a working example, but try:
SELECT
MIN(WorkDate) OVER (PARTITION BY UserId ORDER BY WorkHour) [ReportingDate]
FROM <YourTable>
WHERE WorkDate >= CAST(DATEADD(DAY, -1, GETDATE()) AS DATE)
I'll update when I've got a working example, but try:
SELECT
MIN(WorkDate) OVER (PARTITION BY UserId ORDER BY WorkHour) [ReportingDate]
FROM <YourTable>
WHERE WorkDate >= CAST(DATEADD(DAY, -1, GETDATE()) AS DATE)
answered Nov 15 '18 at 11:18
Jim JimsonJim Jimson
686414
686414
This will be a historical report so it might be run sometimes for a period in the past, ie last week.
– Jess8766
Nov 15 '18 at 11:39
Is there a shift ID or something that identifies a shift?
– Jim Jimson
Nov 15 '18 at 18:04
add a comment |
This will be a historical report so it might be run sometimes for a period in the past, ie last week.
– Jess8766
Nov 15 '18 at 11:39
Is there a shift ID or something that identifies a shift?
– Jim Jimson
Nov 15 '18 at 18:04
This will be a historical report so it might be run sometimes for a period in the past, ie last week.
– Jess8766
Nov 15 '18 at 11:39
This will be a historical report so it might be run sometimes for a period in the past, ie last week.
– Jess8766
Nov 15 '18 at 11:39
Is there a shift ID or something that identifies a shift?
– Jim Jimson
Nov 15 '18 at 18:04
Is there a shift ID or something that identifies a shift?
– Jim Jimson
Nov 15 '18 at 18:04
add a comment |
This is a variation of "gaps-and-islands". You can identify the adjacent hours by subtracting an enumerated sequence. After that, you just need to take the max over the group.
select t.*,
min(workdate) over (partition by datediff(hour, - seqnum, workdatehour) as imputed_workdate
from (select t.*,
dateadd(hour, workhour, workdate) as workdatehour,
row_number() over (order by workdate, workhour) as seqnum
from t
) t
datediff(day,
needs to bedateadd(hour,
.
– Salman A
Nov 15 '18 at 12:16
@SalmanA . . . Thank you.
– Gordon Linoff
Nov 15 '18 at 13:25
add a comment |
This is a variation of "gaps-and-islands". You can identify the adjacent hours by subtracting an enumerated sequence. After that, you just need to take the max over the group.
select t.*,
min(workdate) over (partition by datediff(hour, - seqnum, workdatehour) as imputed_workdate
from (select t.*,
dateadd(hour, workhour, workdate) as workdatehour,
row_number() over (order by workdate, workhour) as seqnum
from t
) t
datediff(day,
needs to bedateadd(hour,
.
– Salman A
Nov 15 '18 at 12:16
@SalmanA . . . Thank you.
– Gordon Linoff
Nov 15 '18 at 13:25
add a comment |
This is a variation of "gaps-and-islands". You can identify the adjacent hours by subtracting an enumerated sequence. After that, you just need to take the max over the group.
select t.*,
min(workdate) over (partition by datediff(hour, - seqnum, workdatehour) as imputed_workdate
from (select t.*,
dateadd(hour, workhour, workdate) as workdatehour,
row_number() over (order by workdate, workhour) as seqnum
from t
) t
This is a variation of "gaps-and-islands". You can identify the adjacent hours by subtracting an enumerated sequence. After that, you just need to take the max over the group.
select t.*,
min(workdate) over (partition by datediff(hour, - seqnum, workdatehour) as imputed_workdate
from (select t.*,
dateadd(hour, workhour, workdate) as workdatehour,
row_number() over (order by workdate, workhour) as seqnum
from t
) t
edited Nov 15 '18 at 13:25
answered Nov 15 '18 at 11:54
Gordon LinoffGordon Linoff
787k35311416
787k35311416
datediff(day,
needs to bedateadd(hour,
.
– Salman A
Nov 15 '18 at 12:16
@SalmanA . . . Thank you.
– Gordon Linoff
Nov 15 '18 at 13:25
add a comment |
datediff(day,
needs to bedateadd(hour,
.
– Salman A
Nov 15 '18 at 12:16
@SalmanA . . . Thank you.
– Gordon Linoff
Nov 15 '18 at 13:25
datediff(day,
needs to be dateadd(hour,
.– Salman A
Nov 15 '18 at 12:16
datediff(day,
needs to be dateadd(hour,
.– Salman A
Nov 15 '18 at 12:16
@SalmanA . . . Thank you.
– Gordon Linoff
Nov 15 '18 at 13:25
@SalmanA . . . Thank you.
– Gordon Linoff
Nov 15 '18 at 13:25
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53317810%2ffind-first-day-per-group-where-time-spans-midnight-boundaries%23new-answer', 'question_page');
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
You're going to need to use a window function. Do you have a field that uniquely identifies one of the employees? Like a UserId?
– Jim Jimson
Nov 15 '18 at 10:58
Yep we have a userID and a Username field
– Jess8766
Nov 15 '18 at 10:59
Can we assume that a person never stays more than 23 hours?
– Salman A
Nov 15 '18 at 11:32
This is correct
– Jess8766
Nov 15 '18 at 11:37