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

求调度日历行高计算的SQL方案:统计重叠记录数适配CSS高度

SQL解决方案:统计时间段最大重叠行数

假设表结构

先假设你的船舶调度表结构如下(可根据实际表名/字段名调整):

CREATE TABLE ship_schedules (
    ship_id INT,
    start_date DATE,
    end_date DATE,
    -- 其他字段如船舶名称、任务类型等
);

核心SQL查询

以下SQL会统计指定时间范围内(比如2023-02-05至2023-02-08)的最大重叠记录数,也就是你需要的行高依据值:

WITH event_points AS (
    -- 拆分每条记录为"开始"和"结束"两个事件
    SELECT start_date AS event_date, 1 AS event_type FROM ship_schedules
    WHERE start_date <= '2023-02-08' AND end_date >= '2023-02-05'
    UNION ALL
    SELECT end_date + INTERVAL 1 DAY AS event_date, -1 AS event_type FROM ship_schedules
    WHERE start_date <= '2023-02-08' AND end_date >= '2023-02-05'
),
running_counts AS (
    -- 按事件日期排序,计算累计重叠数
    SELECT 
        event_date,
        SUM(event_type) OVER (ORDER BY event_date) AS current_overlap
    FROM event_points
)
-- 取最大重叠数,就是需要的结果
SELECT MAX(current_overlap) AS max_overlap_rows FROM running_counts;

逻辑说明

  1. 事件拆分:把每条调度记录拆成「开始日期+1」和「结束日期+1天-1」的事件——给结束日期加1天是因为如果A记录到2月8日结束,B记录从2月8日开始,这两条不算重叠,所以结束事件放在次日,确保日期边界判断准确。
  2. 累计计算:按事件日期排序后,用窗口函数累加事件类型(开始加1,结束减1),得到每个时间点的当前重叠记录数。
  3. 取最大值:最终的最大累计值就是该时间段内同时存在的最多记录数,也就是你需要用来计算行高的数值。

与JavaScript结合的思路

  1. 后端执行上述SQL,将max_overlap_rows的结果返回给前端(比如通过接口JSON、内嵌脚本变量等方式)。
  2. 前端JavaScript中,根据这个最大值计算日历行的CSS高度:
    // 假设基础行高为40px(可根据实际UI调整)
    const baseRowHeight = 40;
    // 从后端获取的最大重叠数
    const maxOverlap = 3; 
    // 计算最终行高
    const calendarRowHeight = baseRowHeight * maxOverlap;
    // 给日历行设置高度
    document.querySelectorAll('.calendar-row').forEach(row => {
        row.style.height = `${calendarRowHeight}px`;
    });
    

扩展说明

  • 如果需要按天统计每天的最大重叠数(而非整个时间段),可以在running_counts中按日期分组后取每天的最大值,再整体取最大。
  • 若你的日期字段包含时间(如DATETIME类型),只需去掉DATE转换,直接用原字段即可,逻辑完全通用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 12:45:37