mysql中的PIVOT数据

时间:2012-08-29 06:53:19

标签: mysql

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'

嗨,上面是我的源表(mysql)我想按如下方式交叉数据。

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  '
是的,请有人帮帮我。我非常感谢你的帮助

1 个答案:

答案 0 :(得分: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上查看。