支持DISTINCT函数功能扩展

PolarDB PostgreSQL版(兼容Oracle)提供Oracle兼容SQL语法的支持,允许在DISTINCT查询中使用ORDER BY字段,且该字段可不属于SELECT列。

功能简介

PolarDB PostgreSQL版(兼容Oracle)通过设置polar_enable_distinct_orderby_new_column参数兼容Oracle中以下语法:

SELECT DISTINCT NVL(a, 0)
FROM polar_dob_a
ORDER BY b
LIMIT 10;

核心特性

  • 跨字段排序:允许ORDER BY子句引用未在SELECT列表中出现的字段(如语法描述中的b)。

  • 兼容Oracle行为:兼容Oracle数据库语法,简化迁移适配。

适用场景

  • 数据去重后需要按其他字段排序,例如统计唯一值并按业务字段排序。

  • 需要兼容Oracle查询逻辑的场景。

功能限制

  • 仅支持Oracle语法兼容 2.0且内核小版本为2.0.14.17.33.0及以上。

    说明

    您可在控制台查看内核小版本号,也可以通过SHOW polardb_version;语句查看。如未满足内核小版本要求,请升级内核小版本

  • 仅在启用polar_enable_distinct_orderby_new_column参数时ORDER BY子句引用未在SELECT列表中出现的字段。

  • 排序字段需为表中实际存在的列。

  • 不支持窗口函数或复杂表达式作为排序字段。

注意事项

  • 性能影响

    • 该功能可能会增加排序开销,因为需要临时存储未选择字段的值。

    • 对于大数据量表,建议配合索引优化排序字段。

  • 兼容性警告

    若未启用该功能执行相应语法SQL将返回类似报错ERROR: column "b" must appear in the GROUP BY clause or be used in an aggregate function

使用说明

语法说明

SELECT DISTINCT [column_expression]
FROM [table_name]
[WHERE conditions]
ORDER BY [new_column]
[LIMIT [offset,] row_count];

参数说明

参数

说明

column_expression

需去重的字段或表达式。

new_column

未在SELECT中出现的排序字段。

LIMIT

可选,限制返回行数。

参数配置

PolarDB提供polar_enable_distinct_orderby_new_column参数用于控制是否允许在DISTINCT查询中使用ORDER BY字段,且该字段未出现在SELECT列中。取值范围如下:

  • on:启用该语法支持。

  • off(默认):禁用该语法支持。

支持全局或会话级参数生效范围修改。

示例

  1. 准备测试表,并插入测试数据。

    CREATE TABLE test(a number, b number, c number);
    
    INSERT INTO test (a, b, c) VALUES
    (1, 2, 10.0),
    (2, 1, 20.0),
    (1, 2, 30.0),
    (3, 1, 40.0),
    (2, 4, 50.0);
  2. 启用语法兼容。

    SET polar_enable_distinct_orderby_new_column = on;
  3. 使用该语法进行查询。

    基本用法

    SELECT DISTINCT nvl(a, 0) 
    FROM test 
    ORDER BY b 
    LIMIT 3;

    返回结果如下:

     a 
    ---
     2
     3
     1
    (3 rows)

    WHERE条件

    SELECT DISTINCT nvl(b, 0)
    FROM test
    WHERE c = 50
    ORDER BY a
    LIMIT 3;

    返回结果如下:

     b 
    ---
     4
    (1 row)

    多字段去重

    SELECT DISTINCT a, NVL(c, 0)
    FROM test
    ORDER BY b
    LIMIT 3;

    返回结果如下:

     a | nvl 
    ---+-----
     2 |  20
     3 |  40
     1 |  10
    (3 rows)