合并有重叠的时间区间--AI解法
## 问题描述 一张表记录了多个账户的时间区间,每个账户有多条记录,区间之间可能存在重叠。 **源数据**:  **期望结果**(合并每个账户内所有重叠的区间):  以账户 A 为例: - 前三个区间(6/20~6/29、6/25~7/25、7/20~8/26)互相重叠,合并为 6/20~8/26; - 12/25~1/25 独立; - 4/27~7/27、6/25~7/14、7/10~8/14 重叠,合并为 4/27~8/14; - 9/10~11/12 独立。 B 同理,两个区间重叠合并。 ## SQLazy 分步实现 核心思路:**判断当前区间的开始日期是否大于前面所有区间的最大结束日期**。如果大于,说明当前区间与之前所有区间都不重叠,需要新开一组;否则合并到当前组。  **第 1 步:按账户和开始日期排序** *sort account_id, start_date* 将数据按 account_id 和 start_date 升序排列,确保每个账户内的区间按时间顺序处理。  **第 2 步:计算当前行之前所有行的最大结束日期** *compute end_date[:-1] max as prev_max; partition account_id* 在每个账户分区内,计算**从第一行到当前行的前一行**中 end_date 的最大值,记为 prev_max。  **第 3 步:按条件分段,生成组号** *segment condition start_date > prev_max as gid; partition account_id* 依次检查每行:如果 start_date > prev_max,说明当前区间与之前所有区间不重叠,则新开一组(gid+1);否则归入同一组。  **第 4 步:按账户和组号汇总** *summarize start_date min as start_date, end_date max as end_date; group account_id, gid* 对每组取最早的开始日期和最晚的结束日期,得到合并后的区间。  最后删除辅助列 gid。 **编译生成 SQL** 确认上述 4 步逻辑后,SQLazy 编译器自动生成原生 SQL(以 MySQL 为例): ``` WITH t2 AS ( SELECT account_id, start_date, end_date, MAX(end_date) OVER ( PARTITION BY account_id ORDER BY CASE WHEN account_id IS NULL THEN 1 ELSE 0 END, account_id ASC, CASE WHEN start_date IS NULL THEN 1 ELSE 0 END, start_date ASC ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING ) AS prev_max FROM acc ), t3 AS ( SELECT account_id, start_date, end_date, prev_max, 1 + SUM( CASE WHEN start_date > prev_max THEN 1 ELSE 0 END ) OVER ( PARTITION BY account_id ORDER BY CASE WHEN account_id IS NULL THEN 1 ELSE 0 END, account_id ASC, CASE WHEN start_date IS NULL THEN 1 ELSE 0 END, start_date ASC ) AS gid FROM t2 ) SELECT account_id, MIN(start_date) AS start_date, MAX(end_date) AS end_date FROM t3 GROUP BY account_id, gid ORDER BY account_id, start_date; ``` 你不需要读懂或调试这段 SQL,只需确认前面 4 步的逻辑正确,编译器就会输出可运行的代码。 **为什么这很重要**  SQLazy 让你**用业务语言描述逻辑,而不是用 SQL 语法写嵌套查询**。这个“合并重叠区间”的例子只用 4 步就表达清楚了——排序、计算前面最大结束日期、按条件分段、汇总。编译器帮你生成最终的 SQL,你只需要验证每一步的业务含义是否正确。