これは機能するはずです:
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;