当前位置: 首页 > article >正文

从 SQL 到 SPL:组内查找最近的匹配记录

MSSQL 数据库的表 mytable,每个 ID 有一个 ConfirmationStarted 和多个 Closed 状态。

CreatedAtIDNewStatus
2022-05-25 23:17:44.000147Active
2022-05-28 05:59:02.000147Closed
2022-05-30 20:48:53.000147Active
2022-06-18 05:59:01.000147Closed
2022-06-21 20:09:48.000147Active
2022-06-25 05:59:01.000147Closed
2022-07-13 00:02:47.000147ConfirmationStarted
2022-07-15 15:33:30.000147ConfirmationDone
2022-08-25 05:59:01.000147Closed
2023-03-08 13:34:57.0001645Draft
2023-03-22 19:58:51.0001645Active
2023-04-29 05:59:02.0001645Closed
2023-05-08 14:50:29.0001645Awarded
2023-05-08 14:53:34.0001645ConfirmationStarted
2023-05-08 17:53:55.0001645ConfirmationDone

现在要在每个 ID 里,找到 ConfirmationStarted 之前的所有的 Closed 中,离 ConfirmationStarted 最近的那条记录,取出记录的 ID 和时间字段。

IDxdate
1472022-06-25 05:59:01.000
16452023-04-29 05:59:02.000

SQL 解法:

With cte AS (
    SELECT ID, CreatedAt, NewStatus,
        ROW_NUMBER() OVER (PARTITION BY ID ORDER BY CreatedAt DESC) AS rn
    FROM mytable
    WHERE NewStatus = 'Closed'
    AND CreatedAt < (
        SELECT CreatedAt FROM mytable AS sub
        WHERE sub.ID = mytable.ID AND sub.NewStatus = 'ConfirmationStarted'
    )
)
SELECT ID, CreatedAt as xdate
FROM cte
WHERE rn = 1
ORDER BY ID;

SQL没有天然序号,需要先用窗口函数生成序号。SQL分组后必须立刻汇总,不能对组内记录进行过滤,只能绕道用多层子查询反复过滤。整体代码有点繁琐又难懂。

SPL有天然序号,还提供有丰富的与位置相关的计算。SPL分组后可以保持分组子集,便于处理组内数据。

 A
1"select ID,CreatedAt,NewStatus from mytable order by CreatedAt”)=mssql.query(
2=A1.group(ID)
3=A2.(~.select@c(NewStatus!="ConfirmationStarted").select@z1(NewStatus=="Closed"))
4=A3.new(ID,CreatedAt:xdate)

A1:从数据库加载数据,按时间排序。

A2:按 ID 分组,但不汇总。

A3:过滤每组数据,先找到 ConfirmationStarted 之前的记录,再从中过滤出 Closed,取倒数第 1 条。函数 select 用于条件过滤,过滤时支持与位置相关的计算,@c 表示从第一个使条件为真的记录开始取,直到遇到使条件为假的记录时停止,@1 表示取结果的第 1 条,@z 表示从后往前过滤。

A2-A4 可以合成一句:=A1.group(ID;~.select@c(NewStatus!="ConfirmationStarted").select@z1(NewStatus=="Closed").CreatedAt:xdate)

SPL已开源免费,欢迎前往乾学院了解更多!

免费下载


http://www.kler.cn/a/488150.html

相关文章:

  • Unity3D使用GaussianSplatting加载高斯泼溅模型
  • C++的标准和C++的编译版本
  • 代码随想录算法训练营day27
  • MySQL - 子查询和相关子查询详解
  • python【数据结构】
  • 机器人技术:ModbusTCP转CCLINKIE网关应用
  • 什么是负载均衡?NGINX是如何实现负载均衡的?
  • NO.3 《机器学习期末复习篇》以题(问答题)促习(人学习),满满干huo,大胆学大胆补!
  • 2025运维故障记 3 | 1/8左右 12306 4天3崩
  • 在vscode上
  • 【电子通识】PWM驱动让有刷直流电机恒流工作
  • 【大模型 RAG技术】Elasticsearch (ES) 构建一个基于 RAG问答系统
  • 【全球气候变化】基于R语言的DICE模型实践技术应用
  • 【机器学习:十三、PyTorch简介及实现】
  • HBuilderX打包ios保姆式教程
  • WPF的自定义控件控件学习
  • ubuntu 20.04 安装docker--小白学习之路
  • 警惕恐怖分子使用 ChatGPT 出谋划策
  • 静态路由配置与调试——计算机网络实训day1
  • 景芯SOC设计实战
  • 【漫话机器学习系列】042.提前停止训练的优势(Early Stopping Advantages)
  • Hadoop3.x 万字解析,从入门到剖析源码
  • Three.js - 打开Web 3D世界的大门
  • 【算法刷题】leetcode hot 100 滑动窗口
  • 高斯函数Gaussian绘制matlab
  • 在FreeBSD、Windows、Ubuntu24三种平台下安装Racket