DB2数据库中机器项目日期区间分组查询的SQL实现方案咨询
解决DB2中机器项目使用时间分段聚合的问题
这个需求本质是要把**同一机器、同一项目的连续时间段(中间被其他项目打断的要分开)**聚合,取每组的最早和最晚日期。在DB2中,我们可以借助窗口函数来实现这个分段分组的逻辑,具体步骤如下:
步骤1:标记连续的同项目分组
首先,我们需要识别哪些行属于同一个连续的项目周期。可以用LAG()窗口函数获取上一行的Project值,当当前行的Project和上一行不同时,说明是一个新分组的开始;然后通过累计求和生成唯一的分组ID。
步骤2:按分组聚合起止日期
拿到分组ID后,我们就可以按Machine name、Description、Project和分组ID进行分组,聚合出每组的最小Start date(作为开始日期)和最大Start date(作为结束日期)。
完整SQL代码
WITH segmented_data AS ( SELECT "Machine name", "Description", "Project", "Start date", -- 生成分组ID:当当前项目和上一行不同时,加1,否则继承之前的分组ID SUM(CASE WHEN LAG("Project") OVER (PARTITION BY "Machine name", "Description" ORDER BY DATE("Start date", 'DD-MM-YYYY')) != "Project" THEN 1 ELSE 0 END) OVER (PARTITION BY "Machine name", "Description" ORDER BY DATE("Start date", 'DD-MM-YYYY')) AS group_id FROM your_table_name ) SELECT "Machine name", "Description", "Project", MIN("Start date") AS "Start date", MAX("Start date") AS "Last date" FROM segmented_data GROUP BY "Machine name", "Description", "Project", group_id ORDER BY "Machine name", "Description", DATE(MIN("Start date"), 'DD-MM-YYYY');
代码说明
LAG("Project") OVER (...):获取当前行之前的同机器、同描述的上一行的Project值,用来判断是否是新分组。SUM(...) OVER (...):累计生成分组ID,每遇到新的项目就增加1,确保同一连续项目的行拥有相同的group_id。- 用
DATE("Start date", 'DD-MM-YYYY')处理日期排序:如果你的Start date是字符串类型,必须转换为日期类型才能保证排序逻辑正确;如果字段本身就是DATE类型,可以直接用"Start date"代替。
验证结果
执行上述SQL后,会输出你期望的分段聚合结果(修正了原期望结果中TEST_2的笔误,原数据里TEST_2只有一行,结束日期应与开始日期一致):
| Machine name | Description | Project | Start date | Last date |
|---|---|---|---|---|
| Mach1 | DB2_AIX | TEST_1 | 07-03-2017 | 07-05-2017 |
| Mach1 | DB2_AIX | TEST_2 | 13-05-2016 | 13-05-2016 |
| Mach1 | DB2_AIX | TEST_1 | 22-05-2017 | 12-06-2017 |
内容的提问来源于stack exchange,提问作者jwillink




