如何在持续时间为1的mysql中获得两行?

时间:2015-01-18 11:38:06

标签: mysql date datetime sum duration

我有像这样的行:

id, start_date, end_date
0, 2000-01-01 20:00:00, 2000-01-01 21:00:00
1, 2000-01-01 23:00:00, 2000-01-02 04:00:00

我需要获得报告结果:

date       | time_online
2000-01-01 | 02:00:00
2000-01-02 | 04:00:00

我的解决方案是错误的因为我只是start_date计数。

SELECT DATE_FORMAT(start_date, '%Y-%m-%d') as date, 
SUM(CASE WHEN EXTRACT(DAY FROM start_date) <> EXTRACT(DAY FROM end_date) 
THEN  
    TIMESTAMPDIFF(SECOND, start_date, DATE_FORMAT(start_date + INTERVAL 1 DAY, '%Y-%m-%d')) 
ELSE 
    TIMESTAMPDIFF(SECOND, start_date, end_date) END) time_online
FROM online
GROUP BY date

结果:

date       | time_online
2000-01-01 | 02:00:00

有人可以帮助我吗?

1 个答案:

答案 0 :(得分:0)

您需要的是一个(虚拟)参考表,其中包含在线表格中每个日期的24小时时间间隔。 您可以使用表本身来执行此操作:

SELECT
    DATE(start_date) + INTERVAL 0 HOUR ref_start,
    DATE(start_date) + INTERVAL 24 HOUR ref_end
FROM
    online
WHERE
    end_date IS NOT NULL
UNION DISTINCT
SELECT
    DATE(end_date) + INTERVAL 0 HOUR ref_start,
    DATE(end_date) + INTERVAL 24 HOUR ref_end
FROM
    online
WHERE
    end_date IS NOT NULL

+ INTERVAL 0 HOUR并非真正需要,我补充说,为清楚起见,DISTINCT关键字也是如此。

如果你把它放在子查询中,那么你可以使用(有点)自我连接带有重叠的记录,并根据值计算差异:

SELECT 
    DATE(r.ref_start) ref_date,
    SEC_TO_TIME(SUM(TIMESTAMPDIFF(SECOND,
        CASE WHEN d.start_date >= r.ref_start
            THEN d.start_date
            ELSE r.ref_start
        END,
        CASE WHEN d.end_date <= r.ref_end
            THEN d.end_date
            ELSE r.ref_end
        END))) time_online
FROM
    (
    SELECT
        DATE(start_date) + INTERVAL 0 HOUR ref_start,
        DATE(start_date) + INTERVAL 24 HOUR ref_end
    FROM
        online
    WHERE
        end_date IS NOT NULL
    UNION DISTINCT
    SELECT
        DATE(end_date) + INTERVAL 0 HOUR ref_start,
        DATE(end_date) + INTERVAL 24 HOUR ref_end
    FROM
        online
    WHERE
        end_date IS NOT NULL
    ) r
JOIN
    online d
    ON d.end_date > r.ref_start
    AND d.start_date < r.ref_end
GROUP BY ref_date