我正在研究一种复杂的mysql查询,以计算某一天员工的总工时。它适用于某些员工,但不适用于其他员工。我创建了一个SQL小提琴,这样你就可以很容易地看到我在说什么。 http://sqlfiddle.com/#!2/6439f/1/0
数据:
CREATE TABLE punches
(
PunchID int auto_increment primary key,
EmpID varchar(6),
Name varchar(20),
PunchDateTime DateTime,
PunchEvent varchar(20),
`In-Out` int
);
INSERT INTO punches
(EmpID, Name, PunchDateTime, PunchEvent, `In-Out`)
VALUES
('0538', 'ROXANNE NIESEN', '2013-06-17 07:27:48', 'clockin', 1),
('0538', 'ROXANNE NIESEN', '2013-06-17 16:57:30', 'clockout', 0),
('1102', 'JEFFERY POTTER', '2013-06-17 07:29:44', 'clockin', 1),
('1102', 'JEFFERY POTTER', '2013-06-17 16:29:57', 'clockout', 0),
('1588', 'BRUCE COLEMAN', '2013-06-17 06:20:48', 'clockin', 1),
('1588', 'BRUCE COLEMAN', '2013-06-17 12:15:18', 'breakout', 0),
('1588', 'BRUCE COLEMAN', '2013-06-17 12:43:58', 'breakin', 1),
('1588', 'BRUCE COLEMAN', '2013-06-17 17:00:37', 'clockout', 0);
查询:
SELECT Name, DATE_FORMAT(p.PunchDateTime, '%m-%d-%Y') AS 'Punch Date',
TIME(SUM(p.PunchDateTime * (1 - 2 * `p`.`In-Out`))) AS 'Hours Worked Time',
SUM(p.PunchDateTime * (1 - 2 * `p`.`In-Out`)) AS 'Hours Worked',
SUM(UNIX_TIMESTAMP(p.PunchDateTime*(1-2*`p`.`In-Out`)))/3600 AS 'Hours Worked Decimal'
FROM punches p
WHERE DATE(p.PunchDateTime) = '2013-06-17'
GROUP BY DATE(p.PunchDateTime), EmpID
结果:
| NAME | PUNCH DATE | HOURS WORKED TIME | HOURS WORKED | HOURS WORKED DECIMAL |
------------------------------------------------------------------------------------------------------
| ROXANNE NIESEN | 06-17-2013 | (null) | 92982 | 380968.9583 |
| JEFFERY POTTER | 06-17-2013 | January, 01 1970 09:00:13+0000 | 90013 | 380968.4992 |
| BRUCE COLEMAN | 06-17-2013 | January, 01 1970 10:51:49+0000 | 105149 | 761933.2653 |
Roxanne的第一个结果应该是返回时间并返回NULL。 Jeffery的第二个工作正常。布鲁斯的第三个回归时间,但是当我做数学时,时间错了。有谁知道这里发生了什么? 谢谢 麦克
答案 0 :(得分:1)
作为世界上最丑陋的查询的参赛者......
SELECT U.Name, U.`Punch Date`, SEC_TO_TIME(SUM(U.delta)) FROM
(
(
SELECT `enter`.Name, `enter`.PunchDateTime AS `time`,
DATE_FORMAT(`enter`.PunchDateTime, '%m-%d-%Y') AS 'Punch Date',
TIMESTAMPDIFF(SECOND, `enter`.PunchDateTime, '2003-05-01 00:00:00') AS `delta`
FROM Punches AS `enter`
WHERE `enter`.`In-Out` = 1
)
UNION
(
SELECT `leave`.Name, `leave`.PunchDateTime AS `time`,
DATE_FORMAT(`leave`.PunchDateTime, '%m-%d-%Y') AS 'Punch Date',
-TIMESTAMPDIFF(SECOND, `leave`.PunchDateTime, '2003-05-01 00:00:00') AS `delta`
FROM Punches AS `leave`
WHERE `leave`.`In-Out` = 0
)
) AS U
GROUP BY U.Name,U.`Punch Date`
通过在SQLFiddle上运行它,我获得了以下结果:
NAME PUNCH DATE SEC_TO_TIME(SUM(U.DELTA)) BRUCE COLEMAN 06-17-2013 10:11:09 JEFFERY POTTER 06-17-2013 09:00:13 ROXANNE NIESEN 06-17-2013 09:29:42
对应每天工作的分钟数。
请注意,白天应该处理任意数量的突破。这不能处理晚上工作的人(即当天办理登机手续,第二天办理退房手续)。
答案 1 :(得分:0)
查看您的数据,您的查询对我来说是不可能的。也许可以使用子查询,但如果是我,我会在应用程序中计算它。如果你的clockin和clockout时间戳是相同的reord,那么它将更容易。但是插入这样的事件意味着首先插入clockin然后用clockout时间更新相同的记录。
在当前布局中,您可以为每位员工选择特定日期的事件并计算小时数。确保您订购事件并处理因任何原因缺少clockin和clockout事件的情况。
最后一部分我看不出你在SQL语句中怎么做。
更新:我现在看到你关于In-Out的想法,但实际上这不是失败证明。一个很好的黑客 - 是的,但不是我依赖的东西。
答案 2 :(得分:0)
对于Roxanne,核心SQL是这样的:
SELECT p.EmpID, (p1.PunchDateTime - p.PunchDateTime) AS t
FROM punches p left join punches p1 on p.EmpID = p1.EmpID
WHERE p.PunchEvent = 'clockin' and p1.PunchEvent = 'clockout'
AND p.EmpID = '0538'
答案 3 :(得分:0)
+ ---------------- + ------------ + ---------------- --- + -------------- + ---------------------- +
|名称|打卡日期|工作小时数|工作小时数|工作小时数十进制|
+ ---------------- + ------------ + ------------------- + -------------- + ---------------------- +
| ROXANNE NIESEN | 06-17-2013 | NULL | 92982 | 380974.9583 |
| JEFFERY POTTER | 06-17-2013 | 09:00:13 | 90013 | 380974.4992 |
| BRUCE COLEMAN | 06-17-2013 | 10:51:49 | 105149 | 761945.2653 | + ---------------- + ------------ + ------------------- + -------------- + ---------------------- +3组,5个警告(0.00秒)
的MySQL>显示警告;
+ --------- + ------ + -------------------------------- ------------- +
|等级|代码|留言|
+ --------- + ------ + -------------------------------- ------------- +
|警告| 1292 |日期时间值不正确:' - 20130617072748'|
|警告| 1292 |日期时间值不正确:' - 20130617072944'|
|警告| 1292 |日期时间值不正确:' - 20130617062048'|
|警告| 1292 |日期时间值不正确:' - 20130617124358'|
|警告| 1292 |截断的错误时间值:'92982'|
+ --------- + ------ + -------------------------------- ------------- +
5行(0.00秒)
抱歉格式错误