这应该有效:
SELECT
username,
CONCAT(
FLOOR(
SUM(
UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(start_time) - 86400 * (
(FLOOR(DATEDIFF(end_time, start_time) / 7) * 2) +
IF(WEEKDAY(end_time) > 4, WEEKDAY(end_time) - 4, 0) +
IF(WEEKDAY(end_time) < WEEKDAY(start_time), 2, 0)
)
) / 86400
),
' days ',
TIME_FORMAT(
SEC_TO_TIME(
SUM(
UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(start_time) - 86400 * (
(FLOOR(DATEDIFF(end_time, start_time) / 7) * 2) +
IF(WEEKDAY(end_time) > 4, WEEKDAY(end_time) - 4, 0) +
IF(WEEKDAY(end_time) < WEEKDAY(start_time), 2, 0)
)
) % 86400
),
'%H hours %i minutes'
)
) AS duration
FROM table
WHERE start_time > CONCAT(YEAR(CURDATE()) -1, '-12-31')
GROUP BY username;
但它假设start_time
并且end_time
永远不会在周末跌倒。
有关工作示例,请参阅http://sqlfiddle.com/#!2/d41d8/3587 。
如果您不关心额外的列,则此查询可以简化为:
SELECT
@diff := SUM(
UNIX_TIMESTAMP(end_time) - UNIX_TIMESTAMP(start_time) - 86400 * (
(FLOOR(DATEDIFF(end_time, start_time) / 7) * 2) +
IF(WEEKDAY(end_time) > 4, WEEKDAY(end_time) - 4, 0) +
IF(WEEKDAY(end_time) < WEEKDAY(start_time), 2, 0)
)
) AS duration_seconds,
CONCAT(
FLOOR(@diff / 86400),
' days ',
TIME_FORMAT(SEC_TO_TIME(@diff % 86400), '%H hours %i minutes')
) AS duration
FROM table
WHERE start_time > CONCAT(YEAR(CURDATE()) -1, '-12-31')
GROUP BY username;