You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求MySQL计算多日课程总课时(时/分)的实现方案

按course_id统计课程总课时的MySQL解决方案

刚好做过类似的需求,直接用MySQL的时间函数就能搞定,完全不用在PHP里额外计算,效率还更高。先回顾下你的表结构(方便其他同学理解):

表名:cm_courses_times_and_venues
核心字段:

  • course_id:课程唯一标识
  • course_start:课程开始时间(datetime类型)
  • course_end:课程结束时间(datetime类型)

方案1:直接输出“X小时Y分钟”的友好格式

这条SQL会直接按课程分组,计算出总课时并转换成易读的格式,跨多天的情况也能准确计算:

SELECT 
    course_id,
    CONCAT(
        FLOOR(SUM(TIMESTAMPDIFF(MINUTE, course_start, course_end)) / 60),
        '小时 ',
        SUM(TIMESTAMPDIFF(MINUTE, course_start, course_end)) % 60,
        '分钟'
    ) AS total_duration
FROM 
    cm_courses_times_and_venues
-- 可选:过滤异常数据(结束时间早于开始时间的记录)
WHERE course_end > course_start
GROUP BY 
    course_id;

方案2:拆分出独立的小时和分钟字段

如果你的业务需要单独使用小时数和分钟数(比如后续做计算或不同展示),可以用这条SQL:

SELECT 
    course_id,
    -- 总小时数(取整)
    FLOOR(SUM(TIMESTAMPDIFF(MINUTE, course_start, course_end)) / 60) AS total_hours,
    -- 剩余分钟数
    SUM(TIMESTAMPDIFF(MINUTE, course_start, course_end)) % 60 AS total_minutes
FROM 
    cm_courses_times_and_venues
WHERE course_end > course_start
GROUP BY 
    course_id;

关键函数说明

  • TIMESTAMPDIFF(MINUTE, start, end):这个函数是核心,它会直接计算两个时间戳之间的分钟差,完全支持跨天场景(比如从2018-04-09 22:00到2018-04-10 02:30,会算出270分钟)。
  • SUM(...):把同一课程下所有课时的分钟差累加,得到总时长的分钟数。
  • FLOOR()和取模运算:把总分钟数转换成小时+分钟的格式,FLOOR取整得到完整的小时数,取模得到剩下的分钟数。

PHP中使用示例(PDO版本)

如果用PHP对接的话,直接执行上面的SQL就行,这里给个简单的PDO示例:

<?php
// 替换成你的数据库配置
$dbConfig = [
    'host' => 'localhost',
    'dbname' => 'your_db_name',
    'user' => 'your_username',
    'pass' => 'your_password'
];

try {
    $pdo = new PDO(
        "mysql:host={$dbConfig['host']};dbname={$dbConfig['dbname']};charset=utf8mb4",
        $dbConfig['user'],
        $dbConfig['pass'],
        [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]
    );

    // 这里用方案1的SQL
    $sql = "
        SELECT 
            course_id,
            CONCAT(
                FLOOR(SUM(TIMESTAMPDIFF(MINUTE, course_start, course_end)) / 60),
                '小时 ',
                SUM(TIMESTAMPDIFF(MINUTE, course_start, course_end)) % 60,
                '分钟'
            ) AS total_duration
        FROM 
            cm_courses_times_and_venues
        WHERE course_end > course_start
        GROUP BY 
            course_id
    ";

    $stmt = $pdo->query($sql);
    $courseDurations = $stmt->fetchAll(PDO::FETCH_ASSOC);

    // 遍历输出结果
    foreach ($courseDurations as $item) {
        echo "课程ID {$item['course_id']} 的总课时:{$item['total_duration']}<br>";
    }
} catch (PDOException $e) {
    die("数据库连接或查询出错:" . $e->getMessage());
}
?>

注意事项

  • 确保你的course_start和course_end字段是datetime或timestamp类型,如果是字符串的话,需要先用STR_TO_DATE()函数转换成时间类型再计算。
  • 建议加上WHERE course_end > course_start的过滤条件,避免因为数据错误导致出现负的时长。

内容的提问来源于stack exchange,提问作者belvie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 07:38:03