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

4

1 回答 1

1

从本质上讲,需要执行自联接以将同一员工在同一日期IN的以下动作与以下动作配对:OUT

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

但是,这不包括有IN记录而没有相应OUT记录的情况。由于 MySQL 没有对 的原生支持FULL OUTER JOIN,因此必须UNION将上述内容与一个类似的查询结合起来,该查询将同一员工在同一日期的动作OUT与之前的动作配对:IN

  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

获得此详细信息后,需要再次将结果与表连接,以提取记录移动的终端:

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'

sqlfiddle上查看。

于 2012-08-29T08:21:48.643 回答