更新时间:2025-06-30 GMT+08:00

窗口函数

表1 窗口函数列表

函数名

与MySQL的差异

LAG()

  • 偏移量N的取值范围不同:

    MySQL中,N只允许是在范围[0, 263-1]整数值。

    GaussDB中,N只允许是在范围[0, 231-1]整数值。

  • 偏移量N的取值形式不同:
    • MySQL中,取值形式如下:
      • 常量字面量的无符号整数。
      • prepare语句中使用?声明的标记参数。
      • 用户自定义的变量。
      • 存储过程中的局部变量。
    • GaussDB中,取值形式如下:
      • 常量字面量的无符号整数。
      • 不支持在prepare语句中使用?声明的标记参数(prepare语句当前有差异)。
      • 用户自定义的变量。
      • 不支持使用存储过程中的局部变量(PLSQL当前不支持)。
  • 该函数作为子查询结合CREATE TABLE AS使用时,单独执行该函数的子查询语句没有报错或告警时:
    • GaussDB在严格模式和宽松模式下,CREATE TABLE AS语句执行成功,建表成功。
    • MySQL在严格模式下,CREATE TABLE AS语句执行可能报错,建表失败。

LEAD()

ROW_NUMBER()

-

RANK()

-

DENSE_RANK()

-

FIRST_VALUE()

-

LAST_VALUE()

-

PERCENT_RANK()

-

NTILE()

-

窗口函数

  • ORDER BY子句排序时,对于NULL值的排序不同:
    • MySQL中,NULL值默认升序排在前面。
    • GaussDB中,NULL值默认升序排在后面。
  • OVER子句中的ORDER BY子句与PARTITION BY子句中使用列别名:
    • MySQL不支持使用列别名。
    • GaussDB支持使用列别名。
  • 当入参为表达式(如1 / col1)形式时,结果的精度存在差异:
    • MySQL会先计算表达式的结果并对表达式结果进行四舍五入,导致最终结果精度下降。
    • GaussDB不会对表达式的结果进行四舍五入。
  • 二进制字符串显示存在差异:
    • MySQL中,将二进制字符串编码为16进制后的编码值进行显示(例如'-4'会显示成编码后的0x2D34)。
    • GaussDB中,显示原字符串的值(例如'-4'会保持显示'-4')。
  • 使用CREATE TABLE AS语法创建表,指定DESC查看表结构时,存在以下差异:
    • MySQL8.0中:
      • 表中的列类型(Type)为BIGINT类型或INT类型时不显示宽度。
      • 表中的列类型(Type)的宽度为0时,显示宽度,如binary(0)。
    • GaussDB中:
      • 表中的列类型(Type)为BIGINT类型或INTEGER类型时会显示宽度。
      • 表中的列类型(Type)的宽度为0时,不显示宽度,如binary(0)只显示成binary。
  • 窗口函数的执行结果依赖于表数据的顺序,在一些场景下(如存在GROUP BY、WHERE、HAVING的场景),GaussDB与MySQL的表数据顺序有差异,会影响窗口函数的执行结果,例如:
    • GaussDB的行为:
      -- 预置表数据。
      m_db=# CREATE TABLE t1(id int,name varchar(20),age int);
      CREATE TABLE
      m_db=# INSERT INTO t1(id, name,age) VALUES (1, 'zwt',90), (2, 'dda',85), (3, 'aab',90), (4, 'aac',78), (5, 'aad',85), (6, 'aae',92), (7, 'aaf',78);
      INSERT 0 7
      m_db=# INSERT INTO t1(id, name,age) VALUES (1, 'zwt',90), (2, 'dda',85), (3, 'aab',90), (4, 'aac',78), (5, 'aad',85), (6, 'aae',92), (7, 'aaf',78);
      INSERT 0 7
      
      -- 表数据的顺序与MySQL有差异导致last_value的取值结果有差异。
      m_db=# SELECT age, last_value(age) over() FROM t1 WHERE id > 0 GROUP BY age HAVING age > 10;
       age | last_value 
      -----+------------
        78 |         85
        90 |         85
        92 |         85
        85 |         85
      (4 rows)
      
      m_db=# DROP TABLE IF EXISTS t1;
      DROP TABLE
    • MySQL的行为:
      # 预置表数据。
      mysql> CREATE TABLE t1(id int,name varchar(20),age int);
      
      Query OK, 0 rows affected (0.12 sec)
      
      mysql> INSERT INTO t1(id, name,age) VALUES (1, 'zwt',90), (2, 'dda',85), (3, 'aab',90), (4, 'aac',78), (5, 'aad',85), (6, 'aae',92), (7, 'aaf',78);
      Query OK, 7 rows affected (0.01 sec)
      Records: 7  Duplicates: 0  Warnings: 0
      
      mysql> INSERT INTO t1(id, name,age) VALUES (1, 'zwt',90), (2, 'dda',85), (3, 'aab',90), (4, 'aac',78), (5, 'aad',85), (6, 'aae',92), (7, 'aaf',78);
      Query OK, 7 rows affected (0.01 sec)
      Records: 7  Duplicates: 0  Warnings: 0
      
      # 表数据的顺序与GaussDB有差异导致last_value的取值结果有差异。
      mysql> SELECT age, last_value(age) over() FROM t1 WHERE id > 0 GROUP BY age HAVING age > 10;
      +------+------------------------+
      | age  | last_value(age) over() |
      +------+------------------------+
      |   90 |                     92 |
      |   85 |                     92 |
      |   78 |                     92 |
      |   92 |                     92 |
      +------+------------------------+
      4 rows in set (0.00 sec)
      
      mysql> DROP TABLE IF EXISTS t1;
      Query OK, 0 rows affected (0.10 sec)