0
RCDID, EmployeeID, LogDate, LogTime, TerminalID, InOut, read

3079184, 'A00075', '2009/10/28', '07:17:10  ', 'VC01 ', 'IN        ', '1'
3079185, 'A00075', '2009/10/28', '17:28:51  ', 'VC01 ', 'OUT       ', '1'
3079186, 'A00038', '2009/10/28', '07:29:17  ', 'VC01 ', 'IN        ', '1'
3079187, 'A00038', '2009/10/28', '17:30:05  ', 'VC01 ', 'OUT       ', '1'
3079188, 'A00085', '2009/10/28', '07:37:34  ', 'VC01 ', 'IN        ', '1'
3079189, 'A00085', '2009/10/28', '17:43:14  ', 'VC01 ', 'IN        ', '1'

Hi, above is my source table (mysql) i want to cross tab the data as follows.

EmployeeID, LogDate, In_location, in_time, Out_location, Out_time
'A00001', '2009/10/28', 'VC01', '08:37:55  ', '', '', 
'A00001', '2009/10/29', 'VC01', '08:09:57  ', 'VC01            ', '17:09:32  '
'A00001', '2009/10/30', 'VC01 ', '09:48:41  ', 'VC01            ', '20:40:37  '
'A00001', '2009/11/03', 'VC01', '08:20:34  ', 'VC01            ', '18:03:34  '
'A00001', '2009/11/04', 'VC01 ', '08:26:49  ', 'VC01            ', '19:21:46  '
'A00001', '2009/11/05', 'VC01', '08:16:00  ', 'VC01            ', '19:26:01  '

can somebody help me please. i am really appreciate your help

0

1 Answer 1

1

Essentially, one needs to perform a self-join to pair up movements IN with the following OUT by the same employee on the same date:

SELECT   a.EmployeeID, a.LogDate,
         a.LogTime AS In_time,
         MIN(b.LogTime) AS Out_time
FROM     my_table a LEFT JOIN my_table b ON
         a.EmployeeID = b.EmployeeID
     AND a.LogDate    = b.LogDate
     AND a.LogTime    < b.LogTime
     AND b.InOut      = 'OUT'
WHERE    a.InOut      = 'IN'
GROUP BY EmployeeID, LogDate, In_time

However, this excludes situations where there is an IN record with no corresponding OUT record. Since MySQL has no native support for FULL OUTER JOIN, one must instead use UNION to combine the above with a similar query that pairs movements OUT with the preceding IN by the same employee on the same date:

  SELECT   a.EmployeeID, a.LogDate,
           a.LogTime AS In_time,
           MIN(b.LogTime) AS Out_time
  FROM     my_table a LEFT JOIN my_table b ON
           a.EmployeeID = b.EmployeeID
       AND a.LogDate    = b.LogDate
       AND a.LogTime    < b.LogTime
       AND b.InOut      = 'OUT'
  WHERE    a.InOut      = 'IN'
  GROUP BY EmployeeID, LogDate, In_time

UNION

  SELECT   a.EmployeeID, a.LogDate,
           MAX(a.LogTime) AS In_time,
           b.LogTime AS Out_time
  FROM     my_table a RIGHT JOIN my_table b ON
           a.EmployeeID = b.EmployeeID
       AND a.LogDate    = b.LogDate
       AND a.LogTime    < b.LogTime
       AND a.InOut      = 'IN'
  WHERE    b.InOut      = 'OUT'
  GROUP BY EmployeeID, LogDate, Out_time

Having obtained this detail, one then needs to join the result with the table again in order to extract the terminals on which the movements were logged:

SELECT t.EmployeeID,
       t.LogDate,
       a.TerminalID AS In_location,
       t.In_time,
       b.TerminalID AS Out_location,
       t.Out_time
FROM (

  SELECT   a.EmployeeID, a.LogDate,
           a.LogTime AS In_time,
           MIN(b.LogTime) AS Out_time
  FROM     my_table a LEFT JOIN my_table b ON
           a.EmployeeID = b.EmployeeID
       AND a.LogDate    = b.LogDate
       AND a.LogTime    < b.LogTime
       AND b.InOut      = 'OUT'
  WHERE    a.InOut      = 'IN'
  GROUP BY EmployeeID, LogDate, In_time

UNION

  SELECT   a.EmployeeID, a.LogDate,
           MAX(a.LogTime) AS In_time,
           b.LogTime AS Out_time
  FROM     my_table a RIGHT JOIN my_table b ON
           a.EmployeeID = b.EmployeeID
       AND a.LogDate    = b.LogDate
       AND a.LogTime    < b.LogTime
       AND a.InOut      = 'IN'
  WHERE    b.InOut      = 'OUT'
  GROUP BY EmployeeID, LogDate, Out_time

) t

  LEFT JOIN my_table a ON
       a.EmployeeID = t.EmployeeID
   AND a.LogDate    = t.LogDate
   AND a.LogTime    = t.In_time
   AND a.InOut      = 'IN'

  LEFT JOIN my_table b ON
       b.EmployeeID = t.EmployeeID
   AND b.LogDate    = t.LogDate
   AND b.LogTime    = t.Out_time
   AND b.InOut      = 'OUT'

See it on sqlfiddle.

Sign up to request clarification or add additional context in comments.

1 Comment

@Chali: No problem. Perhaps you would be so kind as to follow @Omesh's advice and accept answers that solve your problems, or even upvote them if they're useful or helpful.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.