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