Reputation: 101
Sorry I am new to sql world could this statement be checkin time different with checkout time and remove checkinorout from the statement as you well see :
SELECT
USERINFO.Badgenumber AS USERID,
CHECKINOUT.CHECKTIME AS Checkin,
CHECKINOUT.CHECKTIME AS Checkout,
Machines.MachineAlias,
CHECKINOUT.checkinorout
FROM CHECKINOUT
INNER JOIN USERINFO ON CHECKINOUT.USERID = USERINFO.USERID
INNER JOIN Machines ON CHECKINOUT.SENSORID = Machines.MachineNumber
WHERE (CHECKINOUT.CHECKTIME > '2014-09-25 00:00:00.000')
order by checkin
Output:
USERID Checkin Checkout Machines checkinorout
32 2014-09-25 09:12:57.000 2014-09-25 09:12:57.000 HQ Checkin
32 2014-09-25 12:58:51.000 2014-09-25 12:58:51.000 HQ CheckOut
32 2014-09-26 18:03:33.000 2014-09-26 18:03:33.000 HQ Checkin
32 2014-09-26 22:03:11.000 2014-09-26 22:03:11.000 HQ CheckOut
32 2014-09-27 12:57:55.000 2014-09-27 12:57:55.000 HQ Checkin
32 2014-09-27 17:01:32.000 2014-09-27 17:01:32.000 HQ CheckOut
32 2014-09-28 13:05:03.000 2014-09-28 13:05:03.000 HQ Checkin
32 2014-09-28 17:35:29.000 2014-09-28 17:35:29.000 HQ CheckOut
32 2014-09-29 09:18:12.000 2014-09-29 09:18:12.000 HQ Checkin
32 2014-09-29 18:10:43.000 2014-09-29 18:10:43.000 HQ CheckOut
32 2014-09-30 09:12:13.000 2014-09-30 09:12:13.000 HQ Checkin
I need the output be like this
USERID Checkin Checkout Machines
32 2014-09-25 09:12:57.000 2014-09-25 12:58:51.000 HQ
32 2014-09-26 18:03:33.000 2014-09-26 22:03:11.000 HQ
32 2014-09-27 12:57:55.000 2014-09-27 17:01:32.000 HQ
32 2014-09-28 13:05:03.000 2014-09-28 17:35:29.000 HQ
32 2014-09-29 09:18:12.000 2014-09-29 18:10:43.000 HQ
Thanks MR @sgeddes but when i edit your statement to have a result
with cte as (
select *,
row_number() over (partition by userid, checkinorout order by CHECKTIME) rn
from CHECKINOUT
)
select userid,
max(case when checkinorout = 'checkin' then CHECKTIME end) checkin,
max(case when checkinorout = 'checkout' then CHECKTIME end) checkout
from cte where USERID=15 and CHECKTIME between '2014-9-21 00:00:00.000' and '2014-10-25 00:00:00.000'
group by userid , rn
userid checkin checkout
15 NULL 2014-09-21 18:50:24.000
15 NULL 2014-09-22 18:06:15.000
15 NULL 2014-09-23 18:01:30.000
15 NULL 2014-09-24 16:52:36.000
15 NULL 2014-09-25 12:58:51.000
15 NULL 2014-09-26 22:03:11.000
15 NULL 2014-09-27 17:01:32.000
15 NULL 2014-09-28 17:35:29.000
15 NULL 2014-09-29 18:10:43.000
15 NULL 2014-09-30 18:11:19.000
15 NULL 2014-10-01 17:52:49.000
15 NULL 2014-10-12 20:13:10.000
15 2014-09-21 10:17:24.000 2014-10-13 22:13:11.000
15 2014-09-22 09:18:29.000 2014-10-14 21:49:28.000
15 2014-09-23 09:10:15.000 2014-10-15 10:14:09.000
15 2014-09-24 09:43:27.000 2014-10-16 17:55:06.000
15 2014-09-25 09:12:57.000 2014-10-17 23:17:00.000
15 2014-09-26 18:03:33.000 2014-10-20 12:38:22.000
15 2014-09-27 12:57:55.000 2014-10-21 07:31:39.000
15 2014-09-28 13:05:03.000 2014-10-22 05:51:47.000
15 2014-09-29 09:18:12.000 2014-10-24 11:26:06.000
15 2014-09-30 09:12:13.000 NULL
15 2014-10-01 10:16:59.000 NULL
15 2014-10-02 10:13:52.000 NULL
15 2014-10-03 00:59:18.000 NULL
15 2014-10-11 22:07:06.000 NULL
15 2014-10-12 09:58:34.000 NULL
15 2014-10-13 05:09:34.000 NULL
15 2014-10-14 11:42:58.000 NULL
15 2014-10-15 04:48:27.000 NULL
15 2014-10-15 15:49:06.000 NULL
15 2014-10-16 09:14:21.000 NULL
15 2014-10-16 21:14:18.000 NULL
15 2014-10-17 00:59:57.000 NULL
15 2014-10-18 17:42:26.000 NULL
15 2014-10-20 01:22:01.000 NULL
15 2014-10-21 01:24:30.000 NULL
15 2014-10-22 00:10:34.000 NULL
15 2014-10-23 20:01:02.000 NULL
15 2014-10-24 01:08:51.000 NULL
and i need it to be
userid checkin checkout
15 2014-09-21 10:17:24.000 2014-09-21 18:50:24.000
15 2014-09-22 09:18:29.000 2014-09-22 18:06:15.000
15 2014-09-23 09:10:15.000 2014-09-23 18:01:30.000
15 2014-09-24 09:43:27.000 2014-09-24 16:52:36.000
15 2014-09-25 09:12:57.000 2014-09-25 12:58:51.000
15 2014-09-26 18:03:33.000 2014-09-26 22:03:11.000
15 2014-09-27 12:57:55.000 2014-09-27 17:01:32.000
Thanks Mr @slavoo
what i have when i try ....
SELECT
u.Badgenumber AS USERID,
c.CHECKTIME AS Checkout,
checkingOut.time AS Checkin,
m.MachineAlias
FROM CHECKINOUT c
INNER JOIN USERINFO u ON c.USERID = u.USERID
INNER JOIN Machines m ON c.SENSORID = m.MachineNumber
OUTER APPLY
(
SELECT top 1 c2.CHECKTIME as time FROM CHECKINOUT c2
WHERE c2.checkinorout = 'Checkout'
AND c.USERID = c2.USERID
AND c.SENSORID = c2.SENSORID
AND c.CHECKTIME < c2.CHECKTIME
order by c2.CHECKTIME asc
) as checkingOut
WHERE (c.CHECKTIME between '2014-10-19 00:00:00.000' and '2014-10-27 00:00:00.000' )
and u.Badgenumber=660
AND c.checkinorout = 'Checkin'
AND checkingOut.time is not null
order by checkingOut.time
The output:
USERID Checkout Checkin MachineAlias
660 2014-10-19 01:56:47.000 2014-10-19 17:27:41.000 Branch4
660 2014-10-20 02:00:14.000 2014-10-20 17:39:35.000 Branch4
660 2014-10-21 01:55:49.000 2014-10-21 16:57:22.000 Branch4
660 2014-10-22 01:59:23.000 2014-10-25 16:48:29.000 Branch4
660 2014-10-23 16:59:34.000 2014-10-25 16:48:29.000 Branch4
660 2014-10-24 16:58:36.000 2014-10-25 16:48:29.000 Branch4
660 2014-10-25 01:56:47.000 2014-10-25 16:48:29.000 Branch4
and i need it to be
USERID Checkout Checkin MachineAlias
660 2014-10-20 02:00:14.000 2014-10-19 17:27:41.000 Branch4
660 2014-10-21 01:55:49.000 2014-10-20 17:39:35.000 Branch4
660 2014-10-22 01:59:23.000 2014-10-21 16:57:22.000 Branch4
660 Null 2014-10-23 16:59:34.000 Branch4
660 2014-10-25 01:56:47.000 2014-10-24 16:58:36.000 Branch4
660 2014-10-26 00:55:35.000 2014-10-25 16:48:29.000 Branch4
and this is the table i read from it
select USERID ,CHECKTIME,checkinorout from CHECKINOUT where USERID=80 and CHECKTIME between '2014-10-19 00:00:00.000' and '2014-10-27 00:00:00.000'
order by CHECKTIME
and this is the full transaction for this user
80 2014-10-19 01:56:47.000 Checkin
80 2014-10-19 17:27:41.000 CheckOut
80 2014-10-20 02:00:14.000 Checkin
80 2014-10-20 17:39:35.000 CheckOut
80 2014-10-21 01:55:49.000 Checkin
80 2014-10-21 16:57:22.000 CheckOut
80 2014-10-22 01:59:23.000 Checkin
80 2014-10-23 16:59:34.000 Checkin
80 2014-10-24 16:58:36.000 Checkin
80 2014-10-25 01:56:47.000 Checkin
80 2014-10-25 16:48:29.000 CheckOut
80 2014-10-26 00:55:35.000 Checkin
for your note i have script its update the check in or out in checkinorout column
to know this report be finger print check in and check out report and if he found no check in leave it Null and if he found the check out null leave it null ( this employ have shift check in 5:00:00 pm and check out 2:00:00 am ) ; .
Upvotes: 3
Views: 116
Reputation: 6076
SELECT
u.Badgenumber AS USERID,
c.CHECKTIME AS Checkin,
checkingOut.time AS Checkout,
m.MachineAlias
FROM CHECKINOUT c
INNER JOIN users u ON c.USERID = u.USERID
INNER JOIN Machines m ON c.SENSORID = m.MachineNumber
OUTER APPLY
(
SELECT top 1 c2.CHECKTIME as time FROM CHECKINOUT c2
WHERE c2.checkinorout = 'Checkout'
AND c.USERID = c2.USERID
AND c.SENSORID = c2.SENSORID
AND c.CHECKTIME < c2.CHECKTIME
AND CAST(c.CHECKTIME as DATE) = CAST(c2.CHECKTIME as DATE)
order by c2.CHECKTIME asc
) as checkingOut
WHERE (c.CHECKTIME > '2014-09-25 00:00:00.000')
AND c.checkinorout = 'Checkin'
order by checkin
Or this:
SELECT
u.Badgenumber AS USERID,
c.CHECKTIME AS Checkin,
checkingOut.time AS Checkout,
Machines.MachineAlias
FROM CHECKINOUT c
INNER JOIN users u ON c.USERID = u.USERID
INNER JOIN Machines ON c.SENSORID = Machines.MachineNumber
OUTER APPLY
(
SELECT top 1 c2.CHECKTIME as time FROM CHECKINOUT c2
WHERE c2.checkinorout = 'Checkout'
AND c.USERID = c2.USERID
AND c.SENSORID = c2.SENSORID
AND c.CHECKTIME < c2.CHECKTIME
AND NOT EXISTS (SELECT * FROM CHECKINOUT c3
WHERE c3.checkinorout = 'Checkin'
AND c3.USERID = c2.USERID
AND c3.SENSORID = c2.SENSORID
AND c3.CHECKTIME > c.CHECKTIME
AND c3.CHECKTIME < c2.CHECKTIME)
order by c2.CHECKTIME asc
) as checkingOut
WHERE (c.CHECKTIME > '2014-09-25 00:00:00.000')
AND c.checkinorout = 'Checkin'
order by checkin
Upvotes: 1
Reputation: 62831
You can use ROW_NUMBER()
to establish a grouping between your checkins and checkouts. Then you need to pivot your results -- you can use MAX
with CASE
to do that:
Here's a simplified version using a common table expression:
with cte as (
select *,
row_number() over (partition by userid, checkinorout order by checkin) rn
from results
)
select userid,
max(case when checkinorout = 'checkin' then checkin end) checkin,
max(case when checkinorout = 'checkout' then checkout end) checkout,
machines
from cte
group by userid, machines, rn
Edit, given your comments, can you not just use a HAVING
clause to remove the NULL
records?
having max(case when checkinorout = 'checkin' then checkin end) is not null
and max(case when checkinorout = 'checkout' then checkout end) is not null
Upvotes: 1