12
返回列表 发新帖
楼主: hai503

[SQL] 上课时长计算(有时间overlap)

[复制链接]
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
11#
发表于 2020-5-11 23:56 | 只看该作者
2楼的方法是把一整个时间区间打散再聚合,如果时间范围很大,这个方法就比较低效。

使用道具 举报

回复
论坛徽章:
176
20周年集字徽章-20	
日期:2020-10-28 14:31:21ITPUB十周年纪念徽章
日期:2011-11-01 16:24:04ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42ITPUB社区12周年站庆徽章
日期:2013-08-13 16:52:38itpub13周年纪念徽章
日期:2014-10-08 15:21:35ITPUB14周年纪念章
日期:2015-10-26 17:23:44ITPUB15周年纪念
日期:2018-02-09 14:12:58ITPUB18周年纪念章
日期:2018-09-17 10:09:4919周年集字徽章-庆
日期:2019-08-27 15:07:44状元
日期:2015-11-19 12:58:23
12#
 楼主| 发表于 2020-5-12 10:20 | 只看该作者
yaksha1 发表于 2020-5-10 01:01
这个思路挺好的,用过的时间就不参与比较,没有用过的时间就计算在内。版主的方法是先判断重叠的时间,重叠 ...

大版的思路最开始我是想用PL/SQL实现的...

使用道具 举报

回复
论坛徽章:
176
20周年集字徽章-20	
日期:2020-10-28 14:31:21ITPUB十周年纪念徽章
日期:2011-11-01 16:24:04ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42ITPUB社区12周年站庆徽章
日期:2013-08-13 16:52:38itpub13周年纪念徽章
日期:2014-10-08 15:21:35ITPUB14周年纪念章
日期:2015-10-26 17:23:44ITPUB15周年纪念
日期:2018-02-09 14:12:58ITPUB18周年纪念章
日期:2018-09-17 10:09:4919周年集字徽章-庆
日期:2019-08-27 15:07:44状元
日期:2015-11-19 12:58:23
13#
 楼主| 发表于 2025-2-20 10:45 | 只看该作者
(2/20/2025)ChatGPT 聊了几轮给的答案:
WITH CTE AS
------
RawData AS
(SELECT Stu_ID, lesson_ID, start_time, end_time FROM CTE),
OrderedData AS
(SELECT Stu_ID,
         lesson_ID,
         start_time,
         end_time,
         LAG(end_time, 1, start_time) OVER(PARTITION BY Stu_ID, lesson_ID ORDER BY start_time) AS prev_end_time
    FROM RawData),
OverlappingData AS
(SELECT Stu_ID,
         lesson_ID,
         CASE
           WHEN start_time <= prev_end_time THEN
            prev_end_time
           ELSE
            start_time
         END AS effective_start_time,
         end_time,
         prev_end_time
    FROM OrderedData),
MergedData AS
(SELECT Stu_ID, lesson_ID, MIN(effective_start_time) AS start_time, end_time
    FROM (SELECT Stu_ID,
                 lesson_ID,
                 effective_start_time,
                 end_time,
                 SUM(CASE
                       WHEN effective_start_time = prev_end_time THEN
                        0
                       ELSE
                        1
                     END) OVER(PARTITION BY Stu_ID, lesson_ID ORDER BY effective_start_time) AS seg_id
            FROM OverlappingData)
   GROUP BY Stu_ID, lesson_ID, end_time, seg_id)
SELECT Stu_ID, lesson_ID, SUM(end_time - start_time) * 24 * 60 AS duration
  FROM MergedData
GROUP BY Stu_ID, lesson_ID
ORDER BY Stu_ID;

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
14#
发表于 2025-2-21 04:05 | 只看该作者
都什么年代了,该试试新玩意了:
select Stu_ID,lesson_ID,sum(DURATION) as DURATION
from cte
match_recognize(
  partition by Stu_ID,lesson_ID
  order by start_time,end_time
  measures
      (MAX(end_time)-MIN(start_time))*24*60 AS DURATION
  one row per match
  pattern(a* b)
  define a as max(end_time) >= next(start_time)
)
group by Stu_ID,lesson_ID

使用道具 举报

回复
论坛徽章:
519
奥运会纪念徽章:垒球
日期:2008-09-15 01:28:12生肖徽章2007版:鸡
日期:2008-11-17 23:40:58生肖徽章2007版:马
日期:2008-11-18 05:09:48数据库板块每日发贴之星
日期:2008-11-29 01:01:02数据库板块每日发贴之星
日期:2008-12-05 01:01:03生肖徽章2007版:虎
日期:2008-12-10 07:47:462009新春纪念徽章
日期:2009-01-04 14:52:28数据库板块每日发贴之星
日期:2009-02-08 01:01:03生肖徽章2007版:蛇
日期:2009-03-09 22:18:532009日食纪念
日期:2009-07-22 09:30:00
15#
发表于 2025-2-22 06:25 | 只看该作者
开始挑战AI了:我构造了三条数据,答案应该是600, 上面GPT给出的结果却是240:

WITH CTE AS
(SELECT 'A001' AS Stu_ID,
         'L2020040001' AS lesson_ID,
         to_date('4/26/2020 10:00', 'mm/dd/yyyy hh24:mi:ss') AS start_time,
         to_date('4/26/2020 20:00', 'mm/dd/yyyy hh24:mi:ss') AS end_time,
         'Mate 10 pro' AS terminal
    FROM DUAL
  UNION ALL
  SELECT 'A001' AS Stu_ID,
         'L2020040001' AS lesson_ID,
         to_date('4/26/2020 11:00', 'mm/dd/yyyy hh24:mi:ss') AS start_time,
         to_date('4/26/2020 12:00', 'mm/dd/yyyy hh24:mi:ss') AS end_time,
         'iPad' AS terminal
    FROM DUAL
  UNION ALL
  SELECT 'A001' AS Stu_ID,
         'L2020040001' AS lesson_ID,
         to_date('4/26/2020 13:00', 'mm/dd/yyyy hh24:mi:ss') AS start_time,
         to_date('4/26/2020 15:00', 'mm/dd/yyyy hh24:mi:ss') AS end_time,
         'Mate 10 pro' AS terminal
    FROM DUAL
)

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表