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

如何从MySQL表按WORK_ID提取连续日期对用于计算工作日差

解决方法:提取分组内的连续日期对

针对你的需求,因为数据表数据量很大,优先推荐用SQL直接提取日期对,比先把所有数据拉到PHP里处理高效得多。下面分两种场景给出方案:

一、用SQL(推荐,适合大数据量)

如果你的数据库支持窗口函数(比如MySQL 8.0+、PostgreSQL、SQL Server等),可以用LAG()函数来获取每组内的上一个日期,直接生成需要的日期对:

SELECT
    WORK_ID,
    DATE AS current_date,
    LAG(DATE) OVER (PARTITION BY WORK_ID ORDER BY DATE ASC) AS prev_date,
    ROW_NUMBER() OVER (PARTITION BY WORK_ID ORDER BY DATE DESC) AS pair_number
FROM Work
WHERE LAG(DATE) OVER (PARTITION BY WORK_ID ORDER BY DATE ASC) IS NOT NULL
ORDER BY WORK_ID ASC, pair_number ASC;

说明:

  • PARTITION BY WORK_ID:按工作ID分组处理数据
  • ORDER BY DATE ASC:每组内按日期升序排列,LAG(DATE)就能拿到当前日期的前一个更早日期
  • ROW_NUMBER() OVER (...) AS pair_number:给每组内的日期对编号,按日期降序排序后,最新的日期对就是Pair 1,和你要的输出格式完全匹配
  • WHERE ... IS NOT NULL:过滤掉每组的第一个日期(它没有前一个日期,无法形成有效配对)

执行这个SQL后,你会得到结构化的结果集,接着在PHP里遍历即可输出目标格式,同时调用你的工作日计算函数:

// 假设$pdo是你的数据库连接实例
$sql = "上述SQL语句";
$stmt = $pdo->query($sql);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $datePair = "{$row['current_date']} - {$row['prev_date']} (Pair {$row['pair_number']} of work_id {$row['WORK_ID']})";
    echo $datePair . PHP_EOL;
    
    // 调用你的工作日计算函数
    $workDays = kac_is_gunu($row['current_date'], $row['prev_date']);
    // 这里可以根据需求存储或输出计算结果
}

二、PHP处理(适合不支持窗口函数的旧数据库)

如果你的数据库不支持窗口函数,只能先把数据按WORK_ID分组查询出来,再在PHP里处理:

步骤1:查询并分组数据

$sql = "SELECT WORK_ID, DATE FROM Work ORDER BY WORK_ID ASC, DATE ASC";
$stmt = $pdo->query($sql);

$workDates = [];
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
    $workId = $row['WORK_ID'];
    if (!isset($workDates[$workId])) {
        $workDates[$workId] = [];
    }
    $workDates[$workId][] = $row['DATE'];
}

步骤2:遍历分组生成日期对

foreach ($workDates as $workId => $dates) {
    $pairCount = count($dates) - 1; // 每组的配对数等于日期总数减1
    // 从后往前遍历,生成符合要求的配对编号
    for ($i = $pairCount; $i > 0; $i--) {
        $currentDate = $dates[$i];
        $prevDate = $dates[$i-1];
        $pairNumber = $pairCount - $i + 1; // 最新的配对编号为1
        echo "{$currentDate} - {$prevDate} (Pair {$pairNumber} of work_id {$workId})" . PHP_EOL;
        
        // 调用计算函数
        $workDays = kac_is_gunu($currentDate, $prevDate);
        // 处理计算结果
    }
}

注意:

这种方法需要把所有数据加载到PHP内存中,如果数据量特别大(比如百万级以上),可能会出现内存溢出问题,所以还是优先选择SQL窗口函数的方案。

最终输出示例

不管用哪种方法,最终输出都会和你期望的格式一致:

2018-05-16 - 2018-05-15 (Pair 1 of work_id 5)
2018-05-15 - 2018-05-10 (Pair 2 of work_id 5)
2018-05-16 - 2018-05-12 (Pair 1 of work_id 6)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 04:05:09