Reputation: 529
I have a table named 'Logs' with the following values :
CheckDate CheckType CheckTime
-------------------------------------------
2011-11-25 IN 14:40:00
2011-11-25 OUT 14:45:00
2011-11-25 IN 14:50:00
2011-11-25 OUT 14:55:00
2011-11-25 IN 15:00:00
2011-11-25 OUT 15:05:00
2011-11-25 IN 15:15:00
2011-11-25 OUT 15:20:00
2011-11-25 IN 15:25:00
2011-11-25 OUT 15:30:00
2011-11-25 OUT 15:40:00
2011-11-25 IN 15:45:00
I want to use the previous table to produce a result of:
CheckDate CheckIn CheckOut
-----------------------------------------
2011-11-25 14:40:00 14:45:00
2011-11-25 14:50:00 14:55:00
2011-11-25 15:00:00 15:05:00
2011-11-25 15:15:00 15:20:00
2011-11-25 15:25:00 15:30:00
2011-11-25 NULL 15:40:00
2011-11-25 15:45:00 NULL
So far I have come up with this result set :
CheckDate CheckIn CheckOut
-----------------------------------------
2011-11-25 14:40:00 14:45:00
2011-11-25 14:50:00 14:55:00
2011-11-25 15:00:00 15:05:00
2011-11-25 15:15:00 15:20:00
2011-11-25 15:25:00 15:30:00
2011-11-25 15:45:00 NULL
The problem is I cannot generate the log without CheckIns :
CheckDate CheckIn CheckOut
-----------------------------------------
2011-11-25 NULL 15:40:00
The sequence of CheckIn - CheckOut pairing and order is in increasing time value.
EDIT : This is my current query
SELECT Ins.CheckDate,
Ins.CheckTime,
Outs.CheckTime
FROM (SELECT CheckDate,
CheckTime
FROM Logs
WHERE CheckType = 'I') Ins
FULL OUTER JOIN
(SELECT CheckDate,
CheckTime
FROM Logs
WHERE CheckType = 'O') Outs
ON Ins.CheckDate = Outs.CheckDate AND
Ins.CheckTime < Outs.CheckTime
Upvotes: 1
Views: 523
Reputation: 57816
Some of the optimizers doesn't support "FULL OUTER JOIN" of sql So, Query should be:
SELECT Ins.CheckDate,
Ins.CheckTime,
Outs.CheckTime
FROM (SELECT CheckDate,
CheckTime
FROM Logs
WHERE CheckType = 'I') Ins
LEFT OUTER JOIN
(SELECT CheckDate,
CheckTime
FROM Logs
WHERE CheckType = 'O') Outs
ON Ins.CheckDate = Outs.CheckDate AND
Ins.CheckTime < Outs.CheckTime
UNION
SELECT Ins.CheckDate,
Ins.CheckTime,
Outs.CheckTime
FROM (SELECT CheckDate,
CheckTime
FROM Logs
WHERE CheckType = 'I') Ins
RIGHT OUTER JOIN
(SELECT CheckDate,
CheckTime
FROM Logs
WHERE CheckType = 'O') Outs
ON Ins.CheckDate = Outs.CheckDate AND
Ins.CheckTime < Outs.CheckTime
Upvotes: 0
Reputation: 658907
This should work:
;WITH x AS (
SELECT CheckDate, CheckType, CheckTime
,row_number() OVER (ORDER BY CheckDate, CheckTime) As rn
FROM #t
)
SELECT CASE WHEN x.CheckType = 'IN' OR x.rn = 1 THEN x.CheckDate
ELSE y.CheckDate END AS CheckDate
,CASE WHEN x.CheckType = 'IN' THEN x.CheckTime ELSE NULL END AS CheckIn
,CASE WHEN y.CheckType = 'OUT' THEN y.CheckTime
WHEN x.CheckType = 'OUT' THEN x.CheckTime ELSE NULL END AS CheckOut
FROM x
LEFT JOIN x AS y ON y.rn = x.rn + 1
WHERE x.CheckType = 'IN'
OR y.CheckType = 'OUT'
OR x.rn = 1
It produces exactly the output requested and covers special cases where
OUT
is followed by another OUT
(missing IN
)IN
is followed by another IN
(missing OUT
)IN
is followed by nothing (last row).OUT
.Try the working demo on data.SE.
Upvotes: 5