AI取 ConfirmationStarted 之前最近的一条 Closed

简介: 本方案用SQLazy分步解决:按ID和时间排序→遇ConfirmationStarted切段(seg=1为之前记录)→筛选seg=1且NewStatus='Closed'的行→按ID取CreatedAt最大值。语义清晰,自动生成标准SQL,避免手写复杂窗口函数。

问题描述

数据库表 mytable 存储多个 ID 在不同时间点 CreatedAt 的状态 NewStatus,每个 ID 一定有一个 ConfirmationStarted 和一个或多个 Closed 状态。现在要在每个 ID 内,找到 ConfirmationStarted 之前的所有的 Closed 中,离 ConfirmationStarted 最近的那条记录,取出记录的 ID 和时间字段。

源数据
image.png
期望结果
image.png
以 ID=147 为例:

ConfirmationStarted 出现在 2022-07-13,此前的三条 Closed 分别发生在 05-28、06-18、06-25,离它最近的一条是 2022-06-25 05:59:01,正是期望结果中的时间。

ID=1645 的 ConfirmationStarted 出现在 2023-05-08 14:53:34,此前只有一条 Closed(2023-04-29 05:59:02),所以结果取它。

SQLazy 分步实现

核心思路:把每个 ID 的记录按时间排序后,用 segment 在出现 ConfirmationStarted 的地方切段,第一个 ConfirmationStarted 之前的记录自然落在 seg=1;再过滤出 seg=1 且状态为 Closed 的记录,最后按 ID 汇总取 CreatedAt 的最大值,即离 ConfirmationStarted 最近的一条 Closed。
下面逐一解释这些步骤。
image.png
第 1 步:按 ID 和时间升序排序

sort ID, CreatedAt asc

保证每个 ID 内部的记录按时间先后排列,后续分段和取 "最近" 才有依据。
2606444a0dbe5f0f704257341df45630_818c0c566c4c4b289ef24628e1110f3a_Picture3.png
第 2 步:遇到 ConfirmationStarted 就新开一段

segment condition (NewStatus = "ConfirmationStarted") partition ID as seg

这是核心的一步。segment 按 partition ID 在每个 ID 内独立分段;分段条件指明:每当遇到 NewStatus 为 ConfirmationStarted 的记录,就开启新的一段并编号为 seg。这样,第一个 ConfirmationStarted 之前的所有记录都落在 seg=1,ConfirmationStarted 本身及之后的记录 seg 依次递增。一条语句就把 "目标状态之前" 的区间划了出来。

37040b23079ba6b90984aa3082b401d3_0dc42a6ec6fe4738a20329da7e4adfaa_Picture4.png
第 3 步:过滤出目标记录

filter (NewStatus = "Closed" and seg = 1)

只保留 seg=1(第一个 ConfirmationStarted 之前)且状态为 Closed 的记录,这些就是每个 ID 在 ConfirmationStarted 之前的全部 Closed。
f611926b90161c3ba4d2978aa81f02a2_02ebd9b6980c42d5b0ce8a1b337c4d9c_Picture5.png
第 4 步:按 ID 汇总取最近的 Closed 时间

summarize CreatedAt max as CreatedAt; group ID

在每个 ID 内对 CreatedAt 取最大值。因为前面已经按时间升序排列,最大值就是离 ConfirmationStarted 最近的那条 Closed。summarize 直接用 "按 ID 分组、取 CreatedAt 最大" 的业务语义描述聚合,不需要手工编写窗口函数。
f38365dbd557ef1058b7a833476d0e61_ab1fac91035949e2aa119e1cbc83bf73_Picture6.png
编译生成 SQL
确认上述 4 步逻辑后,SQLazy 编译器自动生成原生 SQL(这里是 Oracle 语法):

WITH t2 AS (
        SELECT CreatedAt, ID, NewStatus
            , 1 + SUM(CASE
                WHEN (NewStatus = 'ConfirmationStarted') THEN 1
                ELSE 0
            END) OVER (PARTITION BY ID ORDER BY ID ASC, CreatedAt ASC ROWS UNBOUNDED PRECEDING) AS seg
        FROM mytable
    )
SELECT ID, MAX(CreatedAt) AS CreatedAt
FROM (
    SELECT CreatedAt, ID, NewStatus, seg
    FROM t2
    WHERE (NewStatus = 'Closed'
        AND seg = 1)
) t_3
GROUP BY ID
ORDER BY ID

SQLazy 让你用业务语言描述逻辑,而不是用 SQL 语法写嵌套查询。这类 "按事件切段、再从指定区段取记录" 的问题,核心是给事件流打上区段标记:segment 条件分段功能直接用 "遇到 ConfirmationStarted 就切段" 描述业务语义,partition 让分段在每个 ID 内独立进行。先分段、再过滤、后汇总的分步计算,让每一步的中间结果都可以独立验证;summarize 用 "按 ID 分组、取最大时间" 这样直白的语句完成聚合,编译器自动生成可运行的 SQL。

相关文章
人工智能 缓存 前端开发
12720 75
|
5天前
|
人工智能 自然语言处理 安全
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
本文聚焦阿里云2026年推出的三款自研AI办公产品,清晰拆解千问办公、Qoder Teams、Qoder CN的差异化定位与能力边界:千问办公主打职场全场景提效,支持自然语言指令一键完成PPT生成、数据分析等高频办公任务;Qoder Teams面向程序员团队,深度整合AI代码生成、团队协同与企业知识库能力;Qoder CN则专为金融、政务等强合规场景打造,实现数据不出境与VPC私有化部署。文章同步给出分场景选型指南与最新活动定价,帮助不同类型的企业按需组合产品,实现业务岗、研发岗与强合规场景的AI能力全覆盖。
阿里云千问办公、Qoder Teams、Qoder CN区别与选择指南:模型能力、适用场景与最新活动参考
Web App开发 人工智能 API
1605 2
|
人工智能 JavaScript 开发工具
DeepSeek Harness 本地安装与使用指南
DeepSeek Harness(DSH)是DeepSeek AI开源的Agent运行框架,支持本地文件操作、命令执行与工具调用。基于Cordis插件架构,具备高扩展性与强可控性,适合开发者搭建可控Agent环境或开展模型基准测试。当前为开发者预览版,需Node.js环境,推荐先用`npx @deepseek-ai/dsh web`快速体验。
4963 0
人工智能 Java BI
1709 1
人工智能 JavaScript 测试技术
2671 2
开发工具 Swift git
2014 6
人工智能 JavaScript 测试技术
1272 5

热门文章

最新文章