You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Apache Calcite创建RexWindow?求窗口聚合实现示例

构造ROW_NUMBER()窗口函数的Calcite解析树示例

没错,要构造ROW_NUMBER() over(order by orderno)这类窗口函数的解析树,确实需要通过窗口定义来实现——在Calcite的SqlNode层面,你需要先创建SqlWindow对象定义OVER子句的规则,再将其绑定到ROW_NUMBER()函数调用上。

以下是完整的代码示例:

import org.apache.calcite.sql.*;
import org.apache.calcite.sql.dialect.CalciteSqlDialect;
import org.apache.calcite.sql.fun.SqlStdOperatorTable;
import org.apache.calcite.sql.parser.SqlParserPos;

public class WindowFunctionExample {
    public static void main(String[] args) {
        // 1. 构造OVER子句中的窗口定义:对应order by orderno
        SqlWindow window = SqlWindow.create(
            null,                // 窗口名称,此处无需命名
            SqlNodeList.EMPTY,   // PARTITION BY子句,此处不需要
            SqlNodeList.of(new SqlIdentifier("orderno", SqlParserPos.ZERO)), // ORDER BY字段
            null,                // 窗口框架,默认使用RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW
            SqlParserPos.ZERO
        );

        // 2. 构造ROW_NUMBER()函数调用,并绑定窗口定义
        SqlCall rowNumberFunc = SqlStdOperatorTable.ROW_NUMBER.createCall(
            SqlParserPos.ZERO,
            window // 将窗口传入,对应OVER(...)部分
        );

        // 3. 给窗口函数设置别名id
        SqlNode selectItem = new SqlAsOperator().createCall(
            SqlParserPos.ZERO,
            rowNumberFunc,
            new SqlIdentifier("id", SqlParserPos.ZERO)
        );

        // 4. 构建完整的SqlSelect解析树
        SqlSelect selectStmt = SqlSelect.create(
            null,                // 关键字扩展(如SELECT DISTINCT的DISTINCT)
            SqlNodeList.EMPTY,   // 未使用的扩展项
            SqlNodeList.of(selectItem), // SELECT子句的列/函数列表
            new SqlIdentifier("process", SqlParserPos.ZERO), // FROM表名
            null,                // WHERE子句
            null,                // GROUP BY子句
            null,                // HAVING子句
            null,                // ORDER BY子句
            null,                // LIMIT子句
            null,                // OFFSET子句
            null,                // FETCH子句
            SqlParserPos.ZERO
        );

        // 验证生成的SQL语句
        System.out.println(selectStmt.toSqlString(CalciteSqlDialect.DEFAULT).getSql());
    }
}

运行这段代码后,会输出你需要的SQL语句:

SELECT ROW_NUMBER() OVER (ORDER BY orderno) AS id FROM process

如果是在RexNode层面处理(比如后续的逻辑计划阶段),则会将SqlWindow转换为RexWindow对象,用来描述窗口聚合的范围和规则。

内容的提问来源于stack exchange,提问作者qqqq

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 04:10:40