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

多行列计算time_c与next_time_c间隔时结果异常的原因排查

问题分析与解决

数据表

entity_idtime_cnext_time_c
1'2023-01-02 10:34:36''2023-01-10 15:12:24'
2'2023-03-01 16:10:12''2023-03-20 22:47:59'

需求

计算time_c与next_time_c之间的:

  • 完整时间间隔
  • 排除周六和周日的时间间隔

错误的查询语句

WITH parms (entity_id, start_date, end_date) AS (
 SELECT entity_id, time_c::timestamp, next_time_c::timestamp FROM test_c
), weekend_days (wkend) AS (
 SELECT SUM(CASE WHEN EXTRACT(isodow FROM d) IN (6, 7) THEN 1 ELSE 0 END)
 FROM parms
 CROSS JOIN generate_series(start_date, end_date, interval '1 day') dn(d)
)
SELECT entity_id AS "ID",
 CONCAT(
  extract(day from diff), ' days ',
  extract( hours from diff) , ' hours ',
  extract( minutes from diff) , ' minutes ',
  extract( seconds from diff)::int , ' seconds '
 ) AS "Duration (excluding saturday and sunday)",
 justify_interval(end_date::timestamp - start_date::timestamp) AS "Duration full"
FROM (
 SELECT start_date, end_date, entity_id,
  (end_date-start_date) - (wkend * interval '1 day') AS diff
 FROM parms
 JOIN weekend_days ON true
) sq;

问题现象

  • 单条数据时结果正常:

    IDDuration (excluding saturday and sunday)Duration full
    16 days 4 hours 37 minutes 48 seconds{"days":8,"hours":4,"minutes":37,"seconds":48}
    213 days 6 hours 37 minutes 47 seconds{"days":19,"hours":6,"minutes":37,"seconds":47}
  • 多条数据时排除周末的结果错误:

    IDDuration (excluding saturday and sunday)Duration full
    10 days 4 hours 37 minutes 48 seconds{"days":8,"hours":4,"minutes":37,"seconds":48}
    211 days 6 hours 37 minutes 47 seconds{"days":19,"hours":6,"minutes":37,"seconds":47}

错误原因

weekend_days CTE中,你将所有行的日期范围通过CROSS JOIN合并后,统计了所有行的周末天数总和,而不是按每个entity_id单独统计自身时间范围内的周末天数。当多行数据时,这个总和会被应用到每一行的计算中,导致减去的周末天数远大于当前行实际应扣除的数量,结果自然错误。

修正后的查询语句

需要按entity_id分组,单独统计每个时间区间内的周末天数:

WITH parms (entity_id, start_date, end_date) AS (
 SELECT entity_id, time_c::timestamp, next_time_c::timestamp FROM test_c
), weekend_days AS (
 SELECT 
  p.entity_id,
  SUM(CASE WHEN EXTRACT(isodow FROM d) IN (6, 7) THEN 1 ELSE 0 END) AS wkend
 FROM parms p
 CROSS JOIN generate_series(p.start_date, p.end_date, interval '1 day') dn(d)
 GROUP BY p.entity_id
)
SELECT 
 p.entity_id AS "ID",
 CONCAT(
  EXTRACT(day FROM diff), ' days ',
  EXTRACT(hour FROM diff), ' hours ',
  EXTRACT(minute FROM diff), ' minutes ',
  EXTRACT(second FROM diff)::INT, ' seconds '
 ) AS "Duration (excluding saturday and sunday)",
 justify_interval(p.end_date - p.start_date) AS "Duration full"
FROM parms p
JOIN weekend_days w ON p.entity_id = w.entity_id
CROSS JOIN LATERAL (
 SELECT (p.end_date - p.start_date) - (w.wkend * INTERVAL '1 day') AS diff
) sq;

修正后结果

IDDuration (excluding saturday and sunday)Duration full
16 days 4 hours 37 minutes 48 seconds{"days":8,"hours":4,"minutes":37,"seconds":48}
213 days 6 hours 37 minutes 47 seconds{"days":19,"hours":6,"minutes":37,"seconds":47}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 08:25:13