如何在AQL中实现类似SQL LAG函数的分组排序聚合需求
如何在AQL中实现连续同名文档的分组聚合(替代SQL LAG函数)
要实现按until排序后对连续同名文档分组,并计算每组的最小since、最大until及收集文档ID,AQL可以通过**窗口函数(WINDOW)**结合聚合操作来替代SQL的LAG功能,具体实现如下:
单集合实现语句
FOR doc IN pmevent -- 先按until字段排序,确保连续文档的顺序正确 SORT doc.until ASC -- 定义窗口:包含从结果集起始到当前行的所有数据 WINDOW w = (ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) -- 获取前一行的name,第一行无前置行时用当前name替代 LET prevName = COALESCE(PREV(doc.name, 1), doc.name) -- 判断当前行是否属于新分组(与前一行name不同则标记为新组) LET isNewGroup = doc.name != prevName -- 累加新组标记值,生成唯一分组ID(连续同名文档ID一致) LET groupId = SUM(isNewGroup) OVER w -- 按分组ID和name聚合,收集同组文档 COLLECT groupId = groupId, name = doc.name INTO groupDocs -- 返回分组结果 RETURN { name: name, group: groupId, ids: groupDocs[*].doc._id, maxUntil: MAX(groupDocs[*].doc.until), minSince: MIN(groupDocs[*].doc.since) }
逻辑说明
- 排序:必须先按
until字段排序,这是识别"连续同名"的前提。 - 窗口定义:
WINDOW w指定了计算范围,确保累加分组标记时能覆盖从第一行到当前行的所有数据。 - 前置值获取:
PREV(doc.name, 1)获取前一行的name,用COALESCE处理第一行无前置行的边界情况。 - 分组标记:
isNewGroup标记当前行是否开启新分组,不同名则为true(等价于1),同名则为false(等价于0)。 - 分组ID生成:
SUM(isNewGroup) OVER w累加所有前置行的分组标记值,连续同名的文档会得到相同的groupId。 - 聚合计算:通过
COLLECT按groupId和name分组后,即可计算组内的最小since、最大until,并收集所有文档ID。
多集合扩展思路
如果需要在多集合联合查询中实现此逻辑,只需先通过UNION或UNION_ALL合并多个集合的文档,再执行上述排序、窗口计算及聚合步骤即可,核心逻辑完全一致。
内容的提问来源于stack exchange,提问作者Gary Gendel
相关产品推荐
相关产品推荐

