WINDOW FUNCTION 算子用于实现 SQL 中的分析函数(也叫窗口函数),计算窗口下的相关行的结果。

    窗口函数与聚集函数不同的是,聚集函数一组只能返回一行,而窗口函数每组可以返回多行,组内每一行都是基于窗口的逻辑计算的结果。因此,在执行含有 WINDOW FUNCTION 的 SQL 时 (格式一般为 OVER(...)),都会在生成执行计划的时候分配一个 WINDOW FUNCTION 算子。

    示例:含 WINDOW FUNCTION 算子的执行计划

    1. obclient>CREATE TABLE t1(c1 INT, c2 INT);
    2. Query OK, 0 rows affected (0.12 sec)
    3. obclient>INSERT INTO t1 VALUES(1, 1);
    4. Query OK, 1 rows affected (0.12 sec)
    5. obclient>INSERT INTO t1 VALUES(2, 2);
    6. Query OK, 1 rows affected (0.12 sec)
    7. obclient>INSERT INTO t1 VALUES(3, 3);
    8. Query OK, 1 rows affected (0.12 sec)
    9. Q1:
    10. obclient>EXPLAIN SELECT MAX(c1) OVER(PARTITION BY c1 ORDER BY c2) FROM t1\G;
    11. *************************** 1. row ***************************
    12. Query Plan:
    13. | ========================================
    14. |ID|OPERATOR |NAME|EST. ROWS|COST|
    15. ----------------------------------------
    16. |0 |WINDOW FUNCTION| |3 |45 |
    17. |1 | SORT | |3 |44 |
    18. |2 | TABLE SCAN |T1 |3 |37 |
    19. ========================================
    20. Outputs & filters:
    21. -------------------------------------
    22. 0 - output([T_FUN_MAX(T1.C1)]), filter(nil),
    23. win_expr(T_FUN_MAX(T1.C1)), partition_by([T1.C1]), order_by([T1.C2, ASC]), window_type(RANGE), upper(UNBOUNDED PRECEDING), lower(CURRENT ROW)
    24. 1 - output([T1.C1], [T1.C2]), filter(nil), sort_keys([T1.C1, ASC], [T1.C2, ASC])
    25. 2 - output([T1.C1], [T1.C2]), filter(nil),
    26. access([T1.C1], [T1.C2]), partitions(p0)

    其中,窗口函数中指定了一个 ORDER BY/PARTITION BY 的时候,会在下层分配一个 SORT 算子,将排序结果返回给窗口函数算子使用。

    上述示例中,Q1 查询的执行计划展示中的 outputs & filters 详细列出了 WINDOW FUNCTION 算子的输出信息如下:

    信息名称

    含义

    output

    该算子输出的表达式。

    filter

    该算子上的过滤条件。

    由于示例中 WINDOW FUNCTION 算子没有设置 filter,所以为 nil。

    win_expr

    在窗口中使用何种聚合函数。

    例如,Q1 查询为求 c1 列的最大值,因此为T_FUN_MAX(t1.c1)

    partition_by

    在窗口中按照何种方式分组。

    例如,Q1 查询为按照 c1 列分组,因此为 t1.c1

    order_by

    在窗口中按照何种方式排序。

    例如,Q1 查询为按照 c2 列排序,因此为 t1.c2

    window_type

    窗口类型,包括 range 和 rows 两种:

    • range :按照逻辑位置偏移进行计算窗口上下界限,默认使用 range 方式。

    • rows :按照实际物理位置偏移进行计算窗口上下界限。

    例如,Q1 查询未设置窗口类型,因此选择了默认方式 range。

    upper

    设定窗口的上边界:

    • UNBOUNDED :无边界,选择最大的值(默认)。

    • CURRENT ROW :从当前行开始,如果出现数字则表示移动的行数。

    • PRECEDING :向前取边

    • FOLLOWING:向后取边界。

    例如,Q1 查询设置的上边界为向前无边界。

    lower

    设定窗口的下边界,边界属性设置同 upper。

    例如,Q1 查询设置的下边界为当前行。