ELM
ELM

Reputation: 529

SQL Full Outer Join

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

Answers (2)

Somnath Muluk
Somnath Muluk

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

Erwin Brandstetter
Erwin Brandstetter

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).
  • first row starts with OUT.

Try the working demo on data.SE.

Upvotes: 5

Related Questions